diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..936f829
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*]
+end_of_line = crlf
+insert_final_newline = false
+charset = utf-8
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
\ No newline at end of file
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..85631bc
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,12 @@
+# 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).
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
new file mode 100644
index 0000000..7ef385d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -0,0 +1,25 @@
+---
+name: Bug report
+about: Create a bug report to help us improve
+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.
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
new file mode 100644
index 0000000..ea7dfd0
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -0,0 +1,15 @@
+---
+name: Feature Request
+about: Suggest a feature to be added
+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.
\ No newline at end of file
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..e1498c9
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,12 @@
+**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](../.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
\ No newline at end of file
diff --git a/.github/workflows/arma.yml b/.github/workflows/arma.yml
new file mode 100644
index 0000000..48c80e3
--- /dev/null
+++ b/.github/workflows/arma.yml
@@ -0,0 +1,22 @@
+name: Validate
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ validate:
+ runs-on: ubuntu-latest
+ steps:
+ - 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"
\ No newline at end of file
diff --git a/.github/workflows/hemtt.yml b/.github/workflows/hemtt.yml
new file mode 100644
index 0000000..3acd131
--- /dev/null
+++ b/.github/workflows/hemtt.yml
@@ -0,0 +1,20 @@
+name: HEMTT
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ check:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout the source code
+ uses: actions/checkout@v4
+ - name: Setup HEMTT
+ uses: arma-actions/hemtt@v1
+ - name: Run HEMTT check
+ run: hemtt check
diff --git a/.hemtt/launch.toml b/.hemtt/launch.toml
new file mode 100644
index 0000000..ec554d6
--- /dev/null
+++ b/.hemtt/launch.toml
@@ -0,0 +1,20 @@
+[default]
+workshop = [
+ "450814997", # CBA
+ "2369477168", # ADT
+]
+presets = []
+dlc = []
+parameters = [
+ "C:\\Users\\skull\\OneDrive\\Documents\\Arma 3 - Other Profiles\\CE%2fSPC-0925%20%22Dart%22\\missions\\CWR_Test.VR",
+]
+
+[ace]
+extends = "default"
+workshop = [
+ "463939057", # ACE
+]
+
+[vanillavoice]
+extends = "default"
+optionals = ["vanillavoice"]
\ No newline at end of file
diff --git a/.hemtt/project.toml b/.hemtt/project.toml
index 9d22123..098a905 100644
--- a/.hemtt/project.toml
+++ b/.hemtt/project.toml
@@ -1,10 +1,10 @@
name = "Chat Wheel Redux"
author = "DartRuffian"
-prefix = "CWR"
-mainprefix = "DA"
+prefix = "cwr"
+mainprefix = "z"
[version]
-path = "addons/Core/script_version.hpp"
+path = "addons/main/script_version.hpp"
git_hash = 0
[files]
@@ -13,33 +13,10 @@ include = [
# "logo_cwr_ca.paa",
# "logo_cwr_over_ca.paa",
"LICENSE",
- "README.md"
-]
-exclude = [
- "*.psd"
+ "README.md",
]
+exclude = ["*.psd"]
[properties]
author = "DartRuffian"
-url = "https://github.com/Dart-Armory/ChatWheel-Redux"
-
-[hemtt.launch.default]
-workshop = [
- "450814997", # CBA
- "2369477168" # ADT
-]
-presets = []
-dlc = []
-optionals = []
-parameters = []
-
-[hemtt.launch.ace]
-workshop = [
- "450814997", # CBA
- "463939057", # ACE
- "2369477168" # ADT
-]
-presets = []
-dlc = []
-optionals = []
-parameters = []
\ No newline at end of file
+url = "https://github.com/DartsArmaMods/ChatWheelRedux"
\ No newline at end of file
diff --git a/.hemtt/scripts/update_build.rhai b/.hemtt/scripts/update_build.rhai
index 0010270..9c93e6a 100644
--- a/.hemtt/scripts/update_build.rhai
+++ b/.hemtt/scripts/update_build.rhai
@@ -1,6 +1,6 @@
// Read the current contents of script_version.hpp
let script_version = HEMTT_RFS.join("addons")
- .join("core")
+ .join("main")
.join("script_version.hpp")
.open_file()
.read();
@@ -9,12 +9,11 @@ let script_version = HEMTT_RFS.join("addons")
let prefix = "#define BUILD ";
let current = HEMTT.project().version().build();
let next = current + 1;
-
script_version.replace(prefix + current.to_string(), prefix + next.to_string());
// Write the modified contents to script_version.hpp
HEMTT_RFS.join("addons")
- .join("core")
+ .join("main")
.join("script_version.hpp")
.create_file()
.write(script_version);
\ No newline at end of file
diff --git a/.hemtt/scripts/update_minor.rhai b/.hemtt/scripts/update_minor.rhai
index a6af217..67a88f8 100644
--- a/.hemtt/scripts/update_minor.rhai
+++ b/.hemtt/scripts/update_minor.rhai
@@ -1,6 +1,6 @@
// Read the current contents of script_version.hpp
let script_version = HEMTT_RFS.join("addons")
- .join("core")
+ .join("main")
.join("script_version.hpp")
.open_file()
.read();
@@ -10,11 +10,14 @@ let prefix = "#define MINOR ";
let current = HEMTT.project().version().minor();
let next = current + 1;
+// Updating minor version should reset patch number
script_version.replace(prefix + current.to_string(), prefix + next.to_string());
+current = HEMTT.project().version().patch();
+script_version.replace("#define PATCH " + current.to_string(), "#define PATCH 0");
// Write the modified contents to script_version.hpp
HEMTT_RFS.join("addons")
- .join("core")
+ .join("main")
.join("script_version.hpp")
.create_file()
.write(script_version);
\ No newline at end of file
diff --git a/.hemtt/scripts/update_patch.rhai b/.hemtt/scripts/update_patch.rhai
new file mode 100644
index 0000000..dec6fba
--- /dev/null
+++ b/.hemtt/scripts/update_patch.rhai
@@ -0,0 +1,20 @@
+// Read the current contents of script_version.hpp
+let script_version = HEMTT_RFS.join("addons")
+ .join("main")
+ .join("script_version.hpp")
+ .open_file()
+ .read();
+
+// Replace the current version with the new version
+let prefix = "#define PATCH ";
+let current = HEMTT.project().version().patch();
+let next = current + 1;
+
+script_version.replace(prefix + current.to_string(), prefix + next.to_string());
+
+// Write the modified contents to script_version.hpp
+HEMTT_RFS.join("addons")
+ .join("main")
+ .join("script_version.hpp")
+ .create_file()
+ .write(script_version);
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..d355f19
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+ "recommendations": [
+ "brettmayson.hemtt",
+ "editorconfig.editorconfig"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index fc59685..9db6e05 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -7,9 +7,12 @@
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": false,
- "files.associations":
- {
- "*.hpp": "cpp"
+ "files.associations": {
+ "*.cpp": "cpp",
+ "*.hpp": "cpp",
+ "*.inc": "cpp",
+ "*.cfg": "cpp",
+ "*.rvmat": "cpp"
},
"C_Cpp.errorSquiggles": "disabled"
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 7f69ab0..0000000
--- a/LICENSE
+++ /dev/null
@@ -1 +0,0 @@
-All rights reserved
\ No newline at end of file
diff --git a/addons/ChatWheel/XEH_PREP.hpp b/LICENSE.md
similarity index 100%
rename from addons/ChatWheel/XEH_PREP.hpp
rename to LICENSE.md
diff --git a/PREFIX.code-workspace b/PREFIX.code-workspace
deleted file mode 100644
index 00f52b5..0000000
--- a/PREFIX.code-workspace
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "folders":
- [
- {
- "path": "./"
- },
- {
- "path": "../../../Users/skull/OneDrive/Documents/Arma 3 - Other Profiles/Previews/Screenshots/EditorPreviews/.hemttout/dev"
- }
- ],
- "settings":
- {
- "editor.insertSpaces": true,
- "editor.detectIndentation": false,
-
- "files.autoSave": "onFocusChange",
- "files.trimFinalNewlines": true,
- "files.trimTrailingWhitespace": true,
- "files.insertFinalNewline": false,
-
- "files.associations":
- {
- "*.hpp": "cpp"
- },
-
- "C_Cpp.errorSquiggles": "disabled"
- }
-}
\ No newline at end of file
diff --git a/README.md b/README.md
index d2fe216..838d563 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,46 @@
-
+
+
+
Chat Wheel Redux
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Requires the latest version of CBA A3
+
-
-
-[](https://github.com/DartRuffian/A3-ChatWheel-Redux/graphs/contributors)
-[](https://steamcommunity.com/sharedfiles/filedetails/?id=3005504621)
+**Chat Wheel Redux** (_CWR_) is a mostly client-side communication mod, allowing players without the ability to speak to communicate with other players easier. It is primarily intended for mute players who cannot communicate via microphone, but can also assist deaf or hard-of-hearing players if other players also use the mod to help communicate with them.
-
+The project is entirely **open-source** and any contributions to fix other mods are welcome.
----
+Chat Wheel Redux is mostly feature complete; however, some of the planned features are: messages when taking damage; when a player is knocked unconcious (ACE); or killed. These will be able to be toggled on or off, similar to the automated messages for throwing grenades functions. They may each recieve their own settings in the future for more customization options.
-> "Thank you Dart for making my 'minimum fit for purpose' mod I made for, like, three of my unit members into something legit super accessible to the broader community."
-> - _Jenna_, the original creator of the script this mod is based on. [Source (Legion Studios Discord)](https://ptb.discord.com/channels/461042140756180992/1130867599345987604/1130901200498343938)
+## Contributing
+For new contributers, see the [Contributing Setup & Guidelines](./.github/CONTRIBUTING.md).
-**Chat Wheel Redux** (_CWR_) is a mostly client-side communication mod, allowing players without the ability to speak to communicate with other players easier. It is primarily intended for mute players who cannot communicate via microphone, but can also assist deaf or hard-of-hearing players if other players also use the mod to help communicate with them.
+## Issues
+Experiencing an issue? Check out the [Common Issues post](https://github.com/DartsArmaMods/A3-ChatWheel-Redux/issues/1) to see if your issue is listed.
+If your issue is not listed, please create [a new issue](https://github.com/DartsArmaMods/ChatWheelRedux/issues/new)
-Chat Wheel Redux is mostly feature complete; however, some of the planned features are: messages when taking damage; when a player is knocked unconcious (ACE); or killed. These will be able to be toggled on or off, similar to the automated messages for throwing grenades functions. They may each recieve their own settings in the future for more customization options.
+## Usage and modification
+This mod can be freely used by any player or any non-monetized server.
+You are free to modify the mod for you or your group's own purposes if you:
+ - Notify me on Discord (dartruffian).
+ - Acknowledge that a fork Chat Wheel Redux is included in your mod(s).
-## Issues
-Experiencing an issue? Check out the [Common Issues post](https://github.com/DartRuffian/A3-ChatWheel-Redux/issues/1) to see if your issue is listed.
-If your issue is not listed, please create one with the appropiate [label](https://github.com/DartRuffian/A3-ChatWheel-Redux/labels).
+---
-## Usage & Modification
-This mod can be freely used by any player or any server.
-Future work will remove the need to download and modify the scripts yourself, as the message options available will be moved to a config class instead of being defined in the scripts themselves.
+> "Thank you Dart for making my 'minimum fit for purpose' mod I made for, like, three of my unit members into something legit super accessible to the broader community."
+> - _Jenna_, the original creator of the script this mod is based on. [Source (Legion Studios Discord)](https://ptb.discord.com/channels/461042140756180992/1130867599345987604/1130901200498343938)
\ No newline at end of file
diff --git a/Tools/addon_includes.txt b/Tools/addon_includes.txt
deleted file mode 100644
index 308f7ff..0000000
--- a/Tools/addon_includes.txt
+++ /dev/null
@@ -1 +0,0 @@
-*.p3d;*.paa;*.rvmat;*.wss;*.sqf;*.wav;*.ogg
\ No newline at end of file
diff --git a/Tools/build.bat b/Tools/build.bat
deleted file mode 100644
index c8516ff..0000000
--- a/Tools/build.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-@echo off
-hemtt.exe script update_build.rhai
-hemtt.exe build
-pause
\ No newline at end of file
diff --git a/Tools/launch.bat b/Tools/launch.bat
deleted file mode 100644
index 46b1451..0000000
--- a/Tools/launch.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-@echo off
-if "%~1"=="" (
- set option=default
-) else (
- set option=%1
-)
-hemtt.exe launch %option%
-pause
\ No newline at end of file
diff --git a/Tools/release.bat b/Tools/release.bat
deleted file mode 100644
index 3c84fe0..0000000
--- a/Tools/release.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-@echo off
-hemtt.exe script update_minor.rhai
-hemtt.exe release
-pause
\ No newline at end of file
diff --git a/addons/ChatWheel/$PBOPREFIX$ b/addons/ChatWheel/$PBOPREFIX$
deleted file mode 100644
index 09f0843..0000000
--- a/addons/ChatWheel/$PBOPREFIX$
+++ /dev/null
@@ -1 +0,0 @@
-DA\CWR\addons\ChatWheel
\ No newline at end of file
diff --git a/addons/ChatWheel/CWR_MessageList.hpp b/addons/ChatWheel/CWR_MessageList.hpp
deleted file mode 100644
index 97a3624..0000000
--- a/addons/ChatWheel/CWR_MessageList.hpp
+++ /dev/null
@@ -1,140 +0,0 @@
-class GVAR(Messages)
-{
- class NeedMedic
- {
- displayName = "Call Medic";
- message = "[vl-NeedMedic]I need a medic!";
- order = 0;
- };
-
- class NeedHelp
- {
- displayName = "Call Help";
- message = "[vl-NeedHelp]I need help!";
- order = 1;
- };
-
- class Apologize
- {
- displayName = "Apologize";
- message = "[vl-Sorry]Sorry!";
- order = 2;
- };
-
- class ThankYou
- {
- displayName = "Thank You";
- message = "[vl-Thanks]Thank you!";
- order = 3;
- };
-
- class Follow
- {
- displayName = "Follow Me";
- message = "[vl-FollowMe]Follow me!";
- order = 4;
- };
-
- class Contact
- {
- displayName = "Contact";
- message = "";
- order = 5;
-
- class Infantry
- {
- displayName = "Infantry";
- message = "[vl-ContactInfantry]Contact! Infantry [direction], bearing [bearing]! [distance]!";
- order = 0;
- };
- class Vehicle
- {
- displayName = "Vehicle";
- message = "[vl-ContactVehicle]Contact! Vehicle [direction], bearing [bearing]! [distance]!";
- order = 1;
- };
- class Fortification
- {
- displayName = "Fortification";
- message = "[vl-ContactFort]Contact! Fortification [direction], bearing [bearing]! [distance]!";
- order = 2;
- };
- };
-
- class NeedAmmo
- {
- displayName = "Need Ammo";
- message = "[vl-NeedAmmo]I need ammo for my [weapon]!";
- order = 6;
- };
-
- class ACECheck
- {
- displayName = "ACE Check";
- message = "";
- order = 7;
-
- class CallCheck
- {
- displayName = "Call";
- message = "[vl-ACECheck]ACE Check!";
- order = 0;
- };
- class StatusGreen
- {
- displayName = "Green";
- message = "[vl-StatusGreen]Status Green!";
- order = 1;
- };
- class StatusYellow
- {
- displayName = "Yellow";
- message = "[vl-StatusYellow]Status Yellow!";
- order = 2;
- };
- class StatusRed
- {
- displayName = "Red";
- message = "[vl-StatusRed]Status Red!";
- order = 3;
- };
- class StatusBlack
- {
- displayName = "Black";
- message = "[vl-StatusBlack]Status Black!";
- order = 4;
- };
- };
-
- class Launcher
- {
- displayName = "Launcher";
- message = "";
- order = 8;
-
- class AskPermission
- {
- displayName = "Permission to Fire?";
- message = "[vl-AskFirePermission]Permission to fire?";
- order = 0;
- };
- class ClearBackblast
- {
- displayName = "Clear Backblast";
- message = "[vl-ClearBackblast]Clear backblast!";
- order = 1;
- };
- class BackblastClear
- {
- displayName = "Backblast Clear";
- message = "[vl-BackblastClear]Backblast clear!";
- order = 2;
- };
- class FireRocket
- {
- displayName = "Rocket Rocket Rocket!";
- message = "[vl-RocketFire]Rocket! Rocket! Rocket!";
- order = 3;
- };
- };
-};
\ No newline at end of file
diff --git a/addons/ChatWheel/CfgEventHandlers.hpp b/addons/ChatWheel/CfgEventHandlers.hpp
deleted file mode 100644
index c7da899..0000000
--- a/addons/ChatWheel/CfgEventHandlers.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-class Extended_PreStart_EventHandlers
-{
- class ADDON
- {
- init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
- };
-};
-
-class Extended_PreInit_EventHandlers
-{
- class ADDON
- {
- init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
- };
-};
-
-// class Extended_PreInit_EventHandlers
-// {
-// class CWR_ConfigureKeybinds
-// {
-// init = QUOTE(call CWR_fnc_configureAddonKeybinds;);
-// };
-// class CWR_ConfigureOptions
-// {
-// init = QUOTE(call CWR_fnc_configureAddonOptions;);
-// };
-// class CWR_ConfigureChatMenus
-// {
-// init = QUOTE(call CWR_fnc_configureMenus;);
-// };
-// };
-
-// class Extended_PostInit_EventHandlers
-// {
-// class CWR_CreateTagDiary
-// {
-// init = QUOTE(call CWR_fnc_createTagMenu;);
-// };
-// class CWR_ThrowGrenadeEH
-// {
-// init = QUOTE(if isClass (configFile >> 'CfgPatches' >> 'ace_common') then { call CWR_fnc_throwGrenadeEHACE; } else { call CWR_fnc_throwGrenadeEH; };);
-// };
-// class CWR_UnconciousEH
-// {
-// init = QUOTE(call CWR_fnc_unconsciousEH);
-// };
-// };
\ No newline at end of file
diff --git a/addons/ChatWheel/addon.toml b/addons/ChatWheel/addon.toml
deleted file mode 100644
index e35366e..0000000
--- a/addons/ChatWheel/addon.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-[binarize]
-enabled = true
-exclude = []
-
-[rapify]
-enabled = true
-exclude = []
-
-[files]
-exclude = []
\ No newline at end of file
diff --git a/addons/ChatWheel/functions/fnc_playLocalSound.sqf b/addons/ChatWheel/functions/fnc_playLocalSound.sqf
deleted file mode 100644
index 13fc463..0000000
--- a/addons/ChatWheel/functions/fnc_playLocalSound.sqf
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "..\script_component.hpp"
-/*
- * Author: Leopard20
- * Edited By DartRuffian
- * Plays a sound local to the current system.
- *
- * Arguments:
- * 0: File path to the sound to play
- * 1: Position to play the sound at in format PositionASL
- *
- * Return Value:
- * None
- *
- * Example:
- * ["file.wss", getPosASL player] call CWR_ChatWheel_fnc_playLocalSound;
- */
-
-params [["_file", "", [""]], ["_position", [0,0,0], [[]], 3]];
-if !(_position isEqualTypeParams [0,0,0]) exitWith {WARNING_2("Array of non-numbers passed to %1. (%2)", _fnc_scriptName, _position);};
-
-if (GVAR(enableVoiceLines)) then
-{
- playSound3D
- [
- _file,
- objNull,
- false,
- _position,
- GVAR(voiceVolume),
- 1,
- 0,
- 0,
- true
- ];
-};
\ No newline at end of file
diff --git a/addons/ChatWheel/functions_old/fn_configureMenus.sqf b/addons/ChatWheel/functions_old/fn_configureMenus.sqf
deleted file mode 100644
index 466e452..0000000
--- a/addons/ChatWheel/functions_old/fn_configureMenus.sqf
+++ /dev/null
@@ -1,108 +0,0 @@
-#define QUOTE(CODE) #CODE
-
-// CBA's implementation of Hashmaps are sorted by insertion order, while BIS game's are not.
-// Order is important since the order of the keys is how they are displayed in the chat menu.
-CWR_messagesHashMap =
-[
- [
- ["Medic", "[vl-NeedMedic]I need a medic!"],
- ["Help", "[vl-NeedHelp]Help me!"],
- ["Apologize", "[vl-Sorry]Sorry!"],
- ["Follow", "[vl-Follow]Follow me!"],
- ["Contact", "[vl-ContactInf]Contact! Infantry [direction], bearing [bearing]! [distance]!"],
- ["Vehicle", "[vl-ContactVic]Contact! Vehicle [direction], bearing [bearing]! [distance]!"],
- ["Fortification", "[vl-ContactFort]Contact! Fortification [direction], bearing [bearing]! [distance]!"],
- ["Low Ammo", "[vl-NeedAmmo]I need ammo for my [weapon]!"],
- ["ACE Check", "[vl-Status]Status [status]!"],
- ["Launchers", "[launcher]"],
- ["Custom 1", "Default Message"], // Configurable messages that can be set in the addon options
- ["Custom 2", "Default Message"],
- ["Custom 3", "Default Message"],
- ["Custom 4", "Default Message"]
- ],
- "Default Message"
-] call CBA_fnc_hashCreate;
-
-
-CWR_launcherMessagesHashMap =
-[
- [
- ["Permission to fire?", "[vl-FirePerm]Permission to fire?"],
- ["Clear backblast!", "[vl-ClearBack]Clear backblast!"],
- ["Backblast clear!", "[vl-BackClear]Backblast clear!"],
- ["Rocket! Rocket! Rocket!", "[vl-RocketFire]Rocket! Rocket! Rocket!"]
- ],
- "Default Message"
-] call CBA_fnc_hashCreate;
-
-
-// Main Root Menu, this is what's opened by the keybind
-[
- "Speak!",
- "CWR_Menu_Root",
- [CWR_messagesHashMap] call CBA_fnc_hashKeys,
- "",
- QUOTE([([CWR_messagesHashMap] call CBA_fnc_hashValues) select %2] call CWR_fnc_sendGroupMessage)
-] call BIS_fnc_createMenu;
-
-
-// Distance Menu, used to get the user's choice of close, medium, or far distances
-CWR_OpenDistanceMenu =
-{
- params ["_message"];
- sleep 0.05;
-
- private _distanceList = ["Close", "Mid", "Far"];
- CWR_distanceMessageList = _distanceList apply { [_message, "[distance]", _x] call CWR_fnc_stringReplace; };
- // distanceMessageList must be global because no other values can be passed to the expression parameter of BIS_fnc_CreateMenu
-
- [
- "How far?",
- "CWR_Menu_Distance",
- _distanceList,
- "",
- QUOTE([[CWR_distanceMessageList select %2] call CWR_fnc_removeQuotes] call CWR_fnc_sendGroupMessage)
- ] call BIS_fnc_createMenu;
-
- showCommandingMenu "#USER:CWR_Menu_Distance_0";
-};
-
-
-CWR_OpenStatusMenu =
-{
- params ["_message"];
- sleep 0.05;
-
- private _statusList = ["Green", "Yellow", "Orange", "Red", "Black"];
- CWR_statusMessageList = _statusList apply { [_message, "[status]", _x] call CWR_fnc_stringReplace; };
-
- [
- "How are you?",
- "CWR_Menu_Status",
- _statusList,
- "",
- QUOTE([[CWR_statusMessageList select %2] call CWR_fnc_removeQuotes] call CWR_fnc_sendGroupMessage)
- ] call BIS_fnc_createMenu;
-
- showCommandingMenu "#USER:CWR_Menu_Status_0";
-};
-
-
-CWR_OpenLauncherMenu =
-{
- params ["_message"];
- sleep 0.05;
-
- CWR_launcherMessageList = ([CWR_launcherMessagesHashMap] call CBA_fnc_hashValues) apply
- { [_message, "[launcher]", _x] call CWR_fnc_stringReplace; };
-
- [
- "Launcher",
- "CWR_Menu_Launcher",
- [CWR_launcherMessagesHashMap] call CBA_fnc_hashKeys,
- "",
- QUOTE([[CWR_launcherMessageList select %2] call CWR_fnc_removeQuotes] call CWR_fnc_sendGroupMessage)
- ] call BIS_fnc_createMenu;
-
- showCommandingMenu "#USER:CWR_Menu_Launcher_0";
-};
diff --git a/addons/ChatWheel/functions_old/fn_createTagMenu.sqf b/addons/ChatWheel/functions_old/fn_createTagMenu.sqf
deleted file mode 100644
index 93ac886..0000000
--- a/addons/ChatWheel/functions_old/fn_createTagMenu.sqf
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Author: DartRuffian
- * Creates a diary tab showing all available tags and what they are replaced with.
- *
- * Arguments:
- * None
- *
- * Return Value:
- * None
- *
- * Example:
- * call CWR_fnc_createTagMenu;
- */
-
-// Normal text settings:
-// "Normal Text "
-
-// Main menu that everything will be in
-player createDiarySubject ["CWR_TagsSubject", "Chat Wheel Tags"];
-
-// List form of text
-private _tags =
-[
- [
- "[distance] - Previously [contact]",
- "[distance] will prompt the user to open a submenu to select a distance.",
- ["Contact! Infantry [distance]!", "Contact! Infantry Close!"]
- ],
- [
- "[weapon]",
- "[weapon] will be replaced with the name of the weapon the player is currently holding.",
- ["I'm holding a [weapon]!", "I'm holding a MX!"]
- ],
- [
- "[launcher]",
- "[launcher] is not intended to be used with custom messages, but is compatible. [launcher] will open the launcher sub-menu, with rocket launcher related options. Such as 'Permission to fire?', 'Clear backblast!', etc.",
- ["[launcher]", "Permission to fire?"]
- ],
- [
- "[status]",
- '[status] will prompt the user to open a submenu and select a status of Green, Yellow, Orange, Red, or Black. The selected option then replaced "[status]".',
- ["Status [status]!", "Status Red!"]
- ],
- [
- "[bearing]",
- "[bearing] is replaced with the compass bearing the player is currently facing.",
- ["Facing [bearing].", "Facing 138."]
- ],
- [
- "[direction]",
- "[direction] is replaced with the direction the player is facing.",
- ["Facing [direction].", "Facing Southeast."]
- ],
- [
- "[vl-ABC]",
- '[vl-ABC] is used to play voicelines for specific actions. The "ABC" part of the tag is the class defined in "CWR_VoiceLines", so in this case, a random file from configFile >> "CWR_VoiceLines" >> "ABC" >> "voiceLines" will be played. If no voicelines are set up, the tag is still removed from the message but no sound effect is played.',
- ["[vl-NeedMedic]I need a medic!", "I need a medic!"]
- ]
-];
-reverse _tags; // Records are created in reverse order, this makes it appear in the same order it's written in
-
-// Orange: c48214
-// Blue : 99cccc
-// Green : bdcc9c
-
-private _formatTitle =
-{
- params ["_str"];
-
- _str = "" + _str + " ";
- _str;
-};
-
-private _formatSubtitle =
-{
- params ["_str"];
-
- _str = "" + _str + " ";
- _str;
-};
-
-private _formatCode =
-{
- params ["_str"];
-
- _str = '"' + _str + '" ';
- _str;
-};
-
-_separator = if (CWR_TagMenu_UseNewLine) then [{ " becomes " }, { " → " }];
-
-// The records are somewhat finnicky, if you add a record to a different a submenu, you can't access the previous submenu.
-// Submenus and records are also added from bottom to top, so everything needs to be added in reverse.
-// Two loops are needed (one for each submenu) because you wouldn't be able to add the title to first submenu if both were in the same loop.
-{
- // Example usages of tags
- private _raw = _x#2#0 call _formatCode;
- private _formatted = _x#2#1 call _formatCode;
-
- player createDiaryRecord ["CWR_TagsSubject", ["Examples", ((_x#0 call _formatSubtitle) + " " + ([_raw, _formatted] joinString _separator))], taskNull, "NONE", false];
-} forEach _tags;
-player createDiaryRecord ["CWR_TagsSubject", ["Examples", "Tag Examples" call _formatTitle], taskNull, "NONE", false];
-
-{
- // List of each tag and what it does
- player createDiaryRecord ["CWR_TagsSubject", ["Message Tags", ((_x#0 call _formatSubtitle) + " " + _x#1)], taskNull, "NONE", false];
-} forEach _tags;
-player createDiaryRecord ["CWR_TagsSubject", ["Message Tags", "Message Tags" call _formatTitle], taskNull, "NONE", false];
diff --git a/addons/ChatWheel/functions_old/fn_findAllVoicelineTags.sqf b/addons/ChatWheel/functions_old/fn_findAllVoicelineTags.sqf
deleted file mode 100644
index 08bd0bf..0000000
--- a/addons/ChatWheel/functions_old/fn_findAllVoicelineTags.sqf
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Author: DartRuffian
- * Finds and returns a list of all voiceline tags present in a string.
- *
- * Arguments:
- * 0: The string to check
- *
- * Return Value:
- * Array of nested arrays: Each lowest level array in format:
- * 0: String - match
- * 1: Number - offset of given match relative to haystack beginning (the provided offset is ignored)
- *
- * Example:
- * "[vl-NeedMedic] test message [vl-NeedAmmo]" call CWR_fnc_findAllVoicelineTags;
- * // Returns [[["[vl-NeedMedic]", 0]], [["[vl-NeedAmmo]", 10]]]
- */
-
-params ["_message"];
-
-private _tags = _message regexFind ["\[vl-[A-z]+\]/g"]; // /g sets global flag, returns all matches
-_tags;
\ No newline at end of file
diff --git a/addons/ChatWheel/functions_old/fn_getConfigNameFromTag.sqf b/addons/ChatWheel/functions_old/fn_getConfigNameFromTag.sqf
deleted file mode 100644
index 39afb45..0000000
--- a/addons/ChatWheel/functions_old/fn_getConfigNameFromTag.sqf
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Author: DartRuffian
- * Removes "[vl-" and "]" from the beginning and end of a voiceline tag.
- *
- * Arguments:
- * 0: The string to check
- *
- * Return Value:
- * String: The config name of the tag
- *
- * Example:
- * "[vl-NeedMedic]" call CWR_fnc_getConfigNameFromTag; // Returns "NeedMedic"
- */
-
-params ["_tag"];
-
-private _configName = _tag trim ["[]", 0]; // Remove "[" or "]" from both sides
-_configName = _configName trim ["vl-", 1]; // Remove "vl-" from the left side
-_configName;
\ No newline at end of file
diff --git a/addons/ChatWheel/functions_old/fn_openChatWheel.sqf b/addons/ChatWheel/functions_old/fn_openChatWheel.sqf
deleted file mode 100644
index 65ad593..0000000
--- a/addons/ChatWheel/functions_old/fn_openChatWheel.sqf
+++ /dev/null
@@ -1 +0,0 @@
-showCommandingMenu "#USER:CWR_Menu_Root_0";
diff --git a/addons/ChatWheel/functions_old/fn_processTags.sqf b/addons/ChatWheel/functions_old/fn_processTags.sqf
deleted file mode 100644
index d483f8d..0000000
--- a/addons/ChatWheel/functions_old/fn_processTags.sqf
+++ /dev/null
@@ -1,81 +0,0 @@
-params ["_message"];
-
-_message call CWR_fnc_devLog;
-_message = switch (true) do
-{
- case ("[distance]" in _message):
- {
- [_message] spawn CWR_OpenDistanceMenu;
- };
-
- case ("[status]" in _message):
- {
- [_message] spawn CWR_OpenStatusMenu;
- };
-
- case ("[bearing]" in _message):
- {
- private _bearing = round direction player;
- _message = [_message, "[bearing]", str _bearing] call CWR_fnc_stringReplace;
- _message call CWR_fnc_processTags;
- };
-
- case ("[direction]" in _message):
- {
- private _bearing = round direction player;
- private _facing = _bearing call CWR_fnc_getDirFromBearing;
-
- _message = [_message, "[direction]", _facing] call CWR_fnc_stringReplace;
- _message call CWR_fnc_processTags;
- };
-
- case ("[weapon]" in _message):
- {
- private _currentWeapon = getText (configFile >> "CfgWeapons" >> currentWeapon player >> "displayName");
- _message = [_message, "[weapon]", _currentWeapon] call CWR_fnc_stringReplace;
- _message call CWR_fnc_processTags;
- };
-
- case ("[launcher]" in _message):
- {
- [_message] spawn CWR_OpenLauncherMenu;
- };
-
- // Voice line tag, plays random sound from config class that matches the name in the tag
- // Checks for "[vl-ABC] ..."
- // regexMatch checks if the entire string matches the pattern, not just a part of it
- case (count (_message call CWR_fnc_findAllVoicelineTags) > 0):
- {
- private _tag = _message call CWR_fnc_findAllVoicelineTags select 0 select 0 select 0; // Returns nested array
- private _configName = _tag call CWR_fnc_getConfigNameFromTag;
-
- _message = [_message, _tag, ""] call CWR_fnc_stringReplace;
-
- private _config = (configFile >> "CWR_VoiceLines" >> _configName);
- if (isClass _config) then
- {
- if ((time - (player getVariable ["CWR_playerLastUsedVoice", -CWR_Voice_CoolDown])) > CWR_Voice_CoolDown ) then
- {
- private _voiceLine = selectRandom getArray (_config >> "voiceLines");
- private _nearbyPlayers = [getPosATL player, CWR_Voice_VoiceRadius, CWR_Voice_RCUnitsSendsMessages] call CWR_fnc_getNearbyPlayers;
-
- {
- [_voiceLine, getPosASL player] remoteExecCall ["CWR_fnc_playLocalSound", _x];
- } forEach _nearbyPlayers;
-
- player setVariable ["CWR_playerLastUsedVoice", time];
- };
- };
-
- _message call CWR_fnc_processTags; // Used to check for further tags
- };
-
- default
- {
- params ["_message"];
-
- _message;
- };
-};
-
-_message;
diff --git a/addons/ChatWheel/functions_old/fn_sendGroupMessage.sqf b/addons/ChatWheel/functions_old/fn_sendGroupMessage.sqf
deleted file mode 100644
index df12c2d..0000000
--- a/addons/ChatWheel/functions_old/fn_sendGroupMessage.sqf
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Author: DartRuffian
- * Sends a message, optionally with [tags], as the player in the player's group.
- *
- * Arguments:
- * message: String - The message to send, optionally with [tags]
- *
- * Return Value:
- * None
- *
- * Example:
- * "I need ammo for my [weapon]" call CWR_fnc_sendGroupMessage;
- * // Sends "I need ammo for my [KC] DC-15S" to all members in the unit's group
- */
-
-params ["_message"];
-
-_message = _message call CWR_fnc_processTags;
-
-// Submenus need to be opened with spawn, which returns the code of the
-// submenu function before an option is selected.
-if (typeName _message isNotEqualTo "STRING") exitWith {};
-
-// Why is chat not global...
-[player, _message] remoteExecCall ["groupChat", group player];
diff --git a/addons/ChatWheel/functions_old/fn_sendLocalMessage.sqf b/addons/ChatWheel/functions_old/fn_sendLocalMessage.sqf
deleted file mode 100644
index 664bc2e..0000000
--- a/addons/ChatWheel/functions_old/fn_sendLocalMessage.sqf
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Authors: DartRuffian
- * Determines whether a message should be sent based on user settings. If yes, it sends the message.
- *
- * Arguments:
- * 0: The sender of the message
- * 1: The message to be sent
- *
- * Return Value:
- * None
- *
- * Example:
- * [player, "Local Message"] remoteExecCall ["CWR_fnc_sendLocalMessage", (units group player)];
- * // Sends the message as the local player to all group members with the setting enabled
- */
-
-params ["_sender", "_message"];
-
-_message = _message call CWR_fnc_processTags;
-
-// Submenus need to be opened with spawn, which returns the code of the
-// submenu function before an option is selected.
-if (typeName _message isNotEqualTo "STRING") exitWith {};
-
-if (CWR_AutoMessages_Enabled) then
-{
- _sender groupChat _message;
-};
diff --git a/addons/ChatWheel/functions_old/fn_throwGrenadeEH.sqf b/addons/ChatWheel/functions_old/fn_throwGrenadeEH.sqf
deleted file mode 100644
index 26ce081..0000000
--- a/addons/ChatWheel/functions_old/fn_throwGrenadeEH.sqf
+++ /dev/null
@@ -1,8 +0,0 @@
-"ace_common not loaded. Starting vanilla Event Handler" call CWR_fnc_devLog;
-
-player addEventHandler ["Fired",
-{
- params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"];
-
- [_unit, _magazine] call CWR_fnc_throwGrenadeMain;
-}];
\ No newline at end of file
diff --git a/addons/ChatWheel/functions_old/fn_throwGrenadeEHACE.sqf b/addons/ChatWheel/functions_old/fn_throwGrenadeEHACE.sqf
deleted file mode 100644
index be70867..0000000
--- a/addons/ChatWheel/functions_old/fn_throwGrenadeEHACE.sqf
+++ /dev/null
@@ -1,8 +0,0 @@
-"ace_common found. Starting ACE Event Handler" call CWR_fnc_devLog;
-
-["ace_firedPlayer",
-{
- params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"];
-
- [_unit, _magazine] call CWR_fnc_throwGrenadeMain;
-}] call CBA_fnc_addEventHandler;
\ No newline at end of file
diff --git a/addons/ChatWheel/functions_old/fn_throwGrenadeMain.sqf b/addons/ChatWheel/functions_old/fn_throwGrenadeMain.sqf
deleted file mode 100644
index c294d7d..0000000
--- a/addons/ChatWheel/functions_old/fn_throwGrenadeMain.sqf
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Author: DartRuffian
- * Main code for the automated grenade messages. Handles formatting the message and sending it to nearby units.
- *
- * Arguments:
- * sender: Object - The sender throwing the grenade
- * magazine: String - The classname of the magazine being used
- *
- * Return Value:
- * None
- *
- * Example:
- * [player, "SmokeShell"] call CWR_fnc_throwGrenadeMain;
- */
-
-
-params ["_sender", "_magazine"];
-
-if !(_magazine isKindOf ["HandGrenade", configFile >> "CfgMagazines"]) exitWith {};
-"Grenade thrown" call CWR_fnc_devLog;
-
-// Determine the type of grenade, assume explosive as default
-private _grenadeType = "Grenade";
-
-if (_magazine isKindOf ["SmokeShell", configFile >> "CfgMagazines"]) then
-{
- _grenadeType = "Smoke";
-};
-
-private _nearbyPlayers = [getPosATL _sender, CWR_Voice_VoiceRadius, CWR_Voice_RCUnitsSendsMessages] call CWR_fnc_getNearbyPlayers;
-
-// Tags are processed here to avoid mismatched data and multiple voice lines playing
-// If processed in the remoteExec, bearing would be *that* player's bearing and the voice
-// line would be played for each unit in range (i.e. 10 players would hear the voiceline 10 times)
-_message = format ["[vl-Throw%1]%1 out, [bearing]!", _grenadeType] call CWR_fnc_processTags;
-
-{
- [_sender, _message] remoteExecCall ["CWR_fnc_sendLocalMessage", _x];
-} forEach _nearbyPlayers;
\ No newline at end of file
diff --git a/addons/ChatWheel/functions_old/fn_unconsciousEH.sqf b/addons/ChatWheel/functions_old/fn_unconsciousEH.sqf
deleted file mode 100644
index 831f865..0000000
--- a/addons/ChatWheel/functions_old/fn_unconsciousEH.sqf
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Author: DartRuffian
- * Event handler for ace_unconscious, plays a voice line when a player is knocked unconscious
- *
- * Arguments:
- * None
- *
- * Return Value:
- * None
- *
- * Example:
- * call CWR_fnc_unconsciousEH;
- */
-
-
-if (isDedicated) exitWith {};
-if !(isClass (configFile >> "CfgPatches" >> "ace_medical")) exitWith {};
-if !(CWR_AutoMessages_Uncon) exitWith {};
-
-[
- "ace_unconscious",
- {
- params ["_unit", "_state"];
- if !(isPlayer _unit) exitWith {};
- if !(_state) exitWith {};
-
- private _nearbyPlayers = [getPosATL _unit, CWR_Voice_VoiceRadius, CWR_Voice_RCUnitsSendsMessages] call CWR_fnc_getNearbyPlayers;
- format ["_nearbyPlayers = %1", _nearbyPlayers] call CWR_fnc_devLog;
-
- _nearbyPlayers = _nearbyPlayers select { [_x] call ace_common_fnc_isAwake; };
- if (count _nearbyPlayers == 0) exitWith {}; // No nearby conscious players
-
- _nearbyPlayers = [_unit, _nearbyPlayers] call CWR_fnc_sortByDistance;
- format ["Sorted _nearbyPlayers = %1", _nearbyPlayers] call CWR_fnc_devLog;
-
- private _closestPlayer = _nearbyPlayers#1;
-
- [_closestPlayer, format ["%1 is down!", name _unit]] call CWR_fnc_sendLocalMessage;
-
- private _isOnCooldown = ((time - (_closestPlayer getVariable ["CWR_playerLastUsedVoice", -CWR_Voice_CoolDown])) < CWR_Voice_CoolDown);
-
- private _config = (configFile >> "CWR_VoiceLines" >> "Unconscious");
- if (isClass _config and !_isOnCooldown) then
- {
- private _voiceLine = selectRandom getArray (_config >> "voiceLines");
- [_voiceLine, getPosASL _closestPlayer] call CWR_fnc_playLocalSound;
- _closestPlayer setVariable ["CWR_playerLastUsedVoice", time];
- };
- }
-] call CBA_fnc_addEventHandler;
\ No newline at end of file
diff --git a/addons/ChatWheel/initKeybinds.inc.sqf b/addons/ChatWheel/initKeybinds.inc.sqf
deleted file mode 100644
index 53ef780..0000000
--- a/addons/ChatWheel/initKeybinds.inc.sqf
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "\a3\ui_f\hpp\defineDIKCodes.inc"
-
-[
- [QUOTE(MOD_NAME), QUOTE(COMPONENT_BEAUTIFIED)],
- GVAR(key_openMenu),
- ["Open Menu", "Opens the custom chat menu."],
- {
- call FUNC(openChatWheel);
- }, // KeyDown
- {}, // KeyUp
- [], // Default Key
- false, // Hold Key
- 0, // Hold Key Delay
- false // Overwrite
-] call CBA_fnc_addKeybind;
diff --git a/addons/ChatWheel/initSettings.inc.sqf b/addons/ChatWheel/initSettings.inc.sqf
deleted file mode 100644
index b62c518..0000000
--- a/addons/ChatWheel/initSettings.inc.sqf
+++ /dev/null
@@ -1,114 +0,0 @@
-// Custom Messages
-[
- QGVAR(customMessages_one),
- "EDITBOX",
- ["Custom Message 1", "Custom message that can be used in the Chat Wheel. Custom messages support [tags]."],
- [QUOTE(MOD_NAME), "Custom Messages"],
- "Default",
- 0,
- {
- [CWR_messagesHashMap, "Custom 1", _this] call CBA_fnc_hashSet;
- }
-] call CBA_fnc_addSetting;
-
-[
- QGVAR(customMessage_two),
- "EDITBOX",
- ["Custom Message 2", "Custom message that can be used in the Chat Wheel. Custom messages support [tags]."],
- [QUOTE(MOD_NAME), "Custom Messages"],
- "Default",
- 0,
- {
- [CWR_messagesHashMap, "Custom 2", _this] call CBA_fnc_hashSet;
- }
-] call CBA_fnc_addSetting;
-
-[
- QGVAR(customMessage_three),
- "EDITBOX",
- ["Custom Message 3", "Custom message that can be used in the Chat Wheel. Custom messages support [tags]."],
- [QUOTE(MOD_NAME), "Custom Messages"],
- "Default",
- 0,
- {
- [CWR_messagesHashMap, "Custom 2", _this] call CBA_fnc_hashSet;
- }
-] call CBA_fnc_addSetting;
-
-[
- QGVAR(customMessage_four),
- "EDITBOX",
- ["Custom Message 4", "Custom message that can be used in the Chat Wheel. Custom messages support [tags]."],
- [QUOTE(MOD_NAME), "Custom Messages"],
- "Default",
- 0,
- {
- [CWR_messagesHashMap, "Custom 2", _this] call CBA_fnc_hashSet;
- }
-] call CBA_fnc_addSetting;
-
-// Automatic Messages
-[
- QGVAR(autoMessages_enabled),
- "CHECKBOX",
- ["Enable Automated Messages", "Enables messages automatically being sent when certain actions are done. Throwing a grenade, getting hurt, etc."],
- [QUOTE(MOD_NAME), "Automatic Messages"],
- true,
- 0,
- {}
-] call CBA_fnc_addSetting;
-
-if (isClass (configFile >> "CfgPatches" >> "ace_medical")) then
-{
- [
- QGVAR(autoMessages_unconEnabled),
- "CHECKBOX",
- ["Unconscious Messages", "When a player goes unconscious, the closest player will make a call out. The max radius is still bound by CWR_Voice_VoiceRadius. Only works with ACE Medical."],
- [QUOTE(MOD_NAME), "Automatic Messages"],
- true,
- 1,
- {}
- ] call CBA_fnc_addSetting;
-};
-
-// Voice Lines
-[
- QGVAR(voice_enabled),
- "CHECKBOX",
- ["Enable Custom VoiceLines", "If enabled, you will hear voice lines when certain actions are done. Such as throwing a grenade or using a chat wheel option."],
- [QUOTE(MOD_NAME), "Voice Lines"],
- true,
- 0,
- {},
- false
-] call CBA_fnc_addSetting;
-
-[
- QGVAR(voice_cooldown),
- "SLIDER",
- ["Custom VoiceLines Cooldown", "The minimum amount of time between custom voicelines."],
- [QUOTE(MOD_NAME), "Voice Lines"],
- [0, 15, 3, 0],
- 1,
- {},
- false
-] call CBA_fnc_addSetting;
-
-[
- QGVAR(voice_radius),
- "SLIDER",
- ["Voice Lines Radius", "The radius of voice lines and automated messages."],
- [QUOTE(MOD_NAME), "Voice Lines"],
- [10, 50, 30, 0],
- 1,
- {},
- false
-] call CBA_fnc_addSetting;
-
-[
- QGVAR(voice_volume),
- "SLIDER",
- ["Voice Lines Volume", "Volume for custom voice lines."],
- [QUOTE(MOD_NAME), "Voice Lines"],
- [0, 5, 1, 1]
-] call CBA_fnc_addSetting;
\ No newline at end of file
diff --git a/addons/ChatWheel/script_component.hpp b/addons/ChatWheel/script_component.hpp
deleted file mode 100644
index b23f5da..0000000
--- a/addons/ChatWheel/script_component.hpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#define COMPONENT ChatWheel
-
-#include "\DA\CWR\addons\Core\script_mod.hpp"
-#include "\DA\CWR\addons\Core\script_macros.hpp"
\ No newline at end of file
diff --git a/addons/Core/$PBOPREFIX$ b/addons/Core/$PBOPREFIX$
deleted file mode 100644
index 15d63ae..0000000
--- a/addons/Core/$PBOPREFIX$
+++ /dev/null
@@ -1 +0,0 @@
-DA\CWR\addons\Core
\ No newline at end of file
diff --git a/addons/Core/addon.toml b/addons/Core/addon.toml
deleted file mode 100644
index e35366e..0000000
--- a/addons/Core/addon.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-[binarize]
-enabled = true
-exclude = []
-
-[rapify]
-enabled = true
-exclude = []
-
-[files]
-exclude = []
\ No newline at end of file
diff --git a/addons/Core/functions/fnc_bearingToDirection.sqf b/addons/Core/functions/fnc_bearingToDirection.sqf
deleted file mode 100644
index 09c0fae..0000000
--- a/addons/Core/functions/fnc_bearingToDirection.sqf
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "..\script_component.hpp"
-/*
- * Author: DartRuffian
- * Converts a bearing, a number from 0 to 360 inclusive, to a direction, North; North East; etc.
- * Values are clamped between 0 and 360.
- *
- * Arguments:
- * 0: Bearing
- *
- * Return Value:
- * The direction
- *
- * Example:
- * 90 call CWR_Core_fnc_getDirFromBearing; // Returns "East"
- */
-
-params [["_bearing", 0, [0]]];
-private ["_direction"];
-
-_bearing = [_bearing, 0, 360] call BIS_fnc_clamp;
-
-_direction = switch (true) do
-{
- case ((_bearing <= 22.5) or (_bearing >= 337.5)): {"North"};
- case (_bearing <= 67.5): {"Northeast"};
- case (_bearing <= 112.5): {"East"};
- case (_bearing <= 157.5): {"Southeast"};
- case (_bearing <= 202.5): {"South"};
- case (_bearing <= 247.5): {"Southwest"};
- case (_bearing <= 292.5): {"West"};
- default {"Northwest"};
-};
-
-_direction;
\ No newline at end of file
diff --git a/addons/Core/functions/fnc_getNearbyPlayers.sqf b/addons/Core/functions/fnc_getNearbyPlayers.sqf
deleted file mode 100644
index 016623f..0000000
--- a/addons/Core/functions/fnc_getNearbyPlayers.sqf
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "..\script_component.hpp"
-/*
- * Authors: DartRuffian
- * Returns an array of players near a given position.
- *
- * Arguments:
- * 0: Position in format PositionAGL or Position2D
- * 1: Radius in meters
- *
- * Return Value:
- * Array of players
- *
- * Example:
- * [getPosAGL player, 30] call CWR_Core_fnc_getNearbyPlayers;
- */
-
-params
-[
- ["_position", [0,0,0], [[]], 3],
- ["_radius", 0, [0]]
-];
-if !(_position isEqualTypeParams [0,0,0]) exitWith {WARNING_2("Array of non-numbers passed to %1. (%2)", _fnc_scriptName, _position);};
-private ["_nearbyUnits"];
-
-_nearbyUnits = _position nearEntities ["CAManBase", _radius];
-_nearbyUnits = _nearbyUnits select {[_x, _includeRemoteControlled] call FUNC(isPlayer);};
-
-_nearbyUnits;
\ No newline at end of file
diff --git a/addons/Core/functions/fnc_removeQuotes.sqf b/addons/Core/functions/fnc_removeQuotes.sqf
deleted file mode 100644
index 306e27b..0000000
--- a/addons/Core/functions/fnc_removeQuotes.sqf
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "..\script_component.hpp"
-/*
- * Author: DartRuffian
- * Removes double and/or single quotes from a given string.
- * By default, removes double and single quotes.
- *
- * Arguments:
- * 0: The original string
- * 1: Remove double quotes
- * 2: Remove single quotes
- *
- * Return Value:
- * The edited string
- *
- * Example:
- * ["Th'is m'essage 'h'as 'a' l'o't' 'o'f' q'u'o't'es in it.", false, true] call CWR_Core_fnc_removeQuotes;
- */
-
-// TODO: Make this function not required.
-
-params [["_str", "", [""]], ["_removeDouble", true, [true]], ["_removeSingle", true, [true]]];
-
-// if (_removeSingle) then
-// {
-// _str = [_str, "'", ""] call FUNC(stringReplace);
-// };
-
-// if (_removeDouble) then
-// {
-// _str = [_str, "'", ""] call FUNC(stringReplace);
-// };
-
-_str;
\ No newline at end of file
diff --git a/addons/Core/functions/fnc_sortByDistance.sqf b/addons/Core/functions/fnc_sortByDistance.sqf
deleted file mode 100644
index f6521ff..0000000
--- a/addons/Core/functions/fnc_sortByDistance.sqf
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "..\script_component.hpp"
-/*
- * Author: DartRuffian
- * Sorts an array of objects or array in format PositionAGL or Position2D.
- *
- * Arguments:
- * 0: Position in format PositionAGL to order objects from
- * 1: Array of objects to sort
- * 2: Sorting order, true for ascending, false for descending
- *
- * Return Value:
- * The sorted objects
- *
- * Example:
- * [player, [unit1]] call CWR_Core_fnc_sortByDistance;
- */
-
-params
-[
- ["_position", [0,0,0], [[]], 3],
- ["_objects", [objNull], []],
- ["_order", true, [true]]
-];
-private ["_sortByDistance"];
-if !(_position isEqualTypeParams [0,0,0]) exitWith {WARNING_2("Array of non-numbers passed to %1. (%2)", _fnc_scriptName, _position);};
-if !(_objects isEqualTypeParams [objNull]) exitWith {WARNING_2("Array of non-objects passed to %1. (%2)", _fnc_scriptName, _position);};
-
-_sortByDistance = _objects apply
-{
- [_position distance _x, _x];
-};
-_sortByDistance sort _order;
-_objects = _sortByDistance apply {_x#1};
-_objects;
\ No newline at end of file
diff --git a/addons/Core/functions/fnc_stringReplace.sqf b/addons/Core/functions/fnc_stringReplace.sqf
deleted file mode 100644
index 30dcf7d..0000000
--- a/addons/Core/functions/fnc_stringReplace.sqf
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "..\script_component.hpp"
-/*
- * Author: Colin J.D. Stewart (PixeL_GaMMa)
- * Edited By DartRuffian
- * Replaces all occurences of substrings in a given string with a given value.
- *
- * Arguments:
- * 0: The original string
- * 1: The substring(s)
- * 2: The string to replace the substring(s) with
- *
- * Return Value:
- * The edited string
- *
- * Example:
- * ["xxx is awesome, I love xxx!", "xxx", "Arma"] call CWR_Core_fnc_stringReplace;
- * ["xxx is awesome, I love yyy!", ["xxx", "yyy"], "Arma"] call CWR_Core_fnc_stringReplace;
- */
-
-params [["_str", "", [""]], ["_find", [""], [""]], ["_replace", "", [""]]];
-private ["_return", "_len", "_pos"];
-
-if (_str isEqualTo "") exitWith {WARNING_1("Empty string passed to %1",_fnc_scriptName)};
-
-if (!(_find isEqualType [])) then
-{
- _find = [_find];
-};
-
-{
- _return = "";
- _len = count _x;
- _pos = _str find _x;
-
- while {(_pos != -1) && (count _str > 0)} do
- {
- _return = _return + (_str select [0, _pos]) + _replace;
-
- _str = (_str select [_pos + _len]);
- _pos = _str find _x;
- };
- _str = _return + _str;
-} forEach _find;
-
-_str;
\ No newline at end of file
diff --git a/addons/Core/script_component.hpp b/addons/Core/script_component.hpp
deleted file mode 100644
index c52a665..0000000
--- a/addons/Core/script_component.hpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#define COMPONENT Core
-
-#include "\DA\CWR\addons\Core\script_mod.hpp"
-#include "\DA\CWR\addons\Core\script_macros.hpp"
\ No newline at end of file
diff --git a/addons/Core/script_macros.hpp b/addons/Core/script_macros.hpp
deleted file mode 100644
index 671f063..0000000
--- a/addons/Core/script_macros.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "\x\cba\addons\main\script_macros_common.hpp"
-
-// Functions
-#undef PREP
-#ifdef DISABLE_COMPILE_CACHE
- #define PREP(fncName) DFUNC(fncName) = compile preprocessFileLineNumbers QPATHTOF(functions\DOUBLES(fnc,fncName).sqf)
-#else
- #define PREP(fncName) [QPATHTOF(functions\DOUBLES(fnc,fncName).sqf), QFUNC(fncName)] call CBA_fnc_compileFunction
-#endif
-
-#define CLASS(var1) DOUBLES(PREFIX,var1)
-#define QCLASS(var1) QUOTE(CLASS(var1))
-
-#define SCOPE_PUBLIC scope = 2; \
-scopeArsenal = 2; \
-scopeCurator = 2
-#define SCOPE_HIDDEN scope = 1; \
-scopeArsenal = 0; \
-scopeCurator = 0
-#define SCOPE_PRIVATE scope = 0; \
-scopeArsenal = 0; \
-scopeCurator = 0
-
-// Booleans
-#define TRUE 1
-#define FALSE 0
\ No newline at end of file
diff --git a/addons/chatwheel/$PBOPREFIX$ b/addons/chatwheel/$PBOPREFIX$
new file mode 100644
index 0000000..883d306
--- /dev/null
+++ b/addons/chatwheel/$PBOPREFIX$
@@ -0,0 +1 @@
+z\cwr\addons\chatwheel
\ No newline at end of file
diff --git a/addons/chatwheel/CWR_ChatWheel_Messages.hpp b/addons/chatwheel/CWR_ChatWheel_Messages.hpp
new file mode 100644
index 0000000..cdc280e
--- /dev/null
+++ b/addons/chatwheel/CWR_ChatWheel_Messages.hpp
@@ -0,0 +1,55 @@
+class GVAR(messages) {
+ class NeedMedic {
+ displayName = CSTRING(messageTitle_NeedMedic);
+ message = CSTRING(message_NeedMedic);
+ order = 0;
+ };
+
+ class NeedHelp {
+ displayName = CSTRING(messageTitle_NeedHelp);
+ message = CSTRING(message_NeedHelp);
+ order = 1;
+ };
+
+ class Apologize {
+ displayName = CSTRING(messageTitle_Apologize);
+ message = CSTRING(message_Apologize);
+ order = 2;
+ };
+
+ class ThankYou {
+ displayName = CSTRING(messageTitle_ThankYou);
+ message = CSTRING(message_ThankYou);
+ order = 3;
+ };
+
+ class Follow {
+ displayName = CSTRING(messageTitle_Follow);
+ message = CSTRING(message_Follow);
+ order = 4;
+ };
+
+ class Contact {
+ displayName = CSTRING(messageTitle_Contact);
+ message = CSTRING(message_Contact);
+ order = 5;
+ };
+
+ class NeedAmmo {
+ displayName = CSTRING(messageTitle_NeedAmmo);
+ message = CSTRING(message_NeedAmmo);
+ order = 6;
+ };
+
+ class ACECheck {
+ displayName = CSTRING(messageTitle_ACECheck);
+ message = CSTRING(message_ACECheck);
+ order = 7;
+ };
+
+ class Launcher {
+ displayName = CSTRING(messageTitle_Launcher);
+ message = CSTRING(message_Launcher);
+ order = 8;
+ };
+};
\ No newline at end of file
diff --git a/addons/chatwheel/CWR_ChatWheel_Tags.hpp b/addons/chatwheel/CWR_ChatWheel_Tags.hpp
new file mode 100644
index 0000000..2978f75
--- /dev/null
+++ b/addons/chatwheel/CWR_ChatWheel_Tags.hpp
@@ -0,0 +1,131 @@
+class GVAR(Tags) {
+ class Bearing {
+ description = CSTRING(tag_Bearing);
+ statement = QUOTE(round direction _this);
+ example = CSTRING(tagExample_Bearing);
+ };
+
+ class Direction {
+ description = CSTRING(tag_Direction);
+ statement = QUOTE(round direction _this call EFUNC(common,bearingToDirection));
+ example = CSTRING(tagExample_Direction);
+ };
+
+ class Weapon {
+ description = CSTRING(tag_Weapon);
+ statement = QUOTE(getText (configFile >> 'CfgWeapons' >> currentWeapon _this >> 'displayName'));
+ example = CSTRING(tagExample_Weapon);
+ };
+
+ class Contact {
+ description = CSTRING(tag_Contact);
+ statement = "";
+ example = CSTRING(tagExample_Contact);
+
+ class Options {
+ // Contact! Infantry [direction], Bearing [bearing]! [distance]!
+ class Infantry {
+ displayName = CSTRING(tagTitle_Contact_Infantry);
+ statement = QUOTE(QLLSTRING(tag_Contact_Infantry));
+ order = 0;
+ };
+ class Vehicle {
+ displayName = CSTRING(tagTitle_Contact_Vehicle);
+ statement = QUOTE(QLLSTRING(tag_Contact_Vehicle));
+ order = 1;
+ };
+ class Fortification {
+ displayName = CSTRING(tagTitle_Contact_Fortification);
+ statement = QUOTE(QLLSTRING(tag_Contact_Fortification));
+ order = 2;
+ };
+ };
+ };
+
+ class Distance {
+ description = CSTRING(tag_Distance);
+ statement = "";
+ example = CSTRING(tagExample_Distance);
+
+ class Options {
+ class Close {
+ displayName = CSTRING(tagTitle_Distance_Close);
+ statement = QUOTE(QLLSTRING(tag_Distance_Close));
+ order = 0;
+ };
+ class Medium {
+ displayName = CSTRING(tagTitle_Distance_Medium);
+ statement = QUOTE(QLLSTRING(tag_Distance_Medium));
+ order = 1;
+ };
+ class Far {
+ displayName = CSTRING(tagTitle_Distance_Far);
+ statement = QUOTE(QLLSTRING(tag_Distance_Far));
+ order = 2;
+ };
+ };
+ };
+
+ class Status {
+ description = CSTRING(tag_Status);
+ statement = "";
+ example = CSTRING(tagExample_Status);
+
+ class Options {
+ class CallCheck {
+ displayName = CSTRING(tagTitle_Status_CallCheck);
+ statement = QUOTE(QLLSTRING(tag_Status_CallCheck));
+ order = 0;
+ };
+ class Green {
+ displayName = CSTRING(tagTitle_Status_Green);
+ statement = QUOTE(QLLSTRING(tag_Status_Green));
+ order = 1;
+ };
+ class Yellow {
+ displayName = CSTRING(tagTitle_Status_Yellow);
+ statement = QUOTE(QLLSTRING(tag_Status_Yellow));
+ order = 2;
+ };
+ class Red {
+ displayName = CSTRING(tagTitle_Status_Red);
+ statement = QUOTE(QLLSTRING(tag_Status_Red));
+ order = 3;
+ };
+ class Black {
+ displayName = CSTRING(tagTitle_Status_Black);
+ statement = QUOTE(QLLSTRING(tag_Status_Black));
+ order = 4;
+ };
+ };
+ };
+
+ class Launcher {
+ description = CSTRING(tag_Launcher);
+ statement = "";
+ example = CSTRING(tagExample_Launcher);
+
+ class Options {
+ class AskPermission {
+ displayName = CSTRING(tagTitle_Launcher_AskPermission);
+ statement = QUOTE(QLLSTRING(tag_Launcher_AskPermission));
+ order = 0;
+ };
+ class ClearBackblast {
+ displayName = CSTRING(tagTitle_Launcher_ClearBackblast);
+ statement = QUOTE(QLLSTRING(tag_Launcher_ClearBackblast));
+ order = 1;
+ };
+ class BackblastClear {
+ displayName = CSTRING(tagTitle_Launcher_BackblastClear);
+ statement = QUOTE(QLLSTRING(tag_Launcher_BackblastClear));
+ order = 2;
+ };
+ class FireRocket {
+ displayName = CSTRING(tagTitle_Launcher_FireRocket);
+ statement = QUOTE(QLLSTRING(tag_Launcher_FireRocket));
+ order = 3;
+ };
+ };
+ };
+};
\ No newline at end of file
diff --git a/addons/chatwheel/CWR_ChatWheel_VoiceLines.hpp b/addons/chatwheel/CWR_ChatWheel_VoiceLines.hpp
new file mode 100644
index 0000000..e53e4b8
--- /dev/null
+++ b/addons/chatwheel/CWR_ChatWheel_VoiceLines.hpp
@@ -0,0 +1,30 @@
+#define EMPTY(var1) \
+ class var1 { \
+ voiceLines[] = {}; \
+ }
+
+class GVAR(VoiceLines) {
+ EMPTY(NeedMedic);
+ EMPTY(NeedHelp);
+ EMPTY(Sorry);
+ EMPTY(Thanks);
+ EMPTY(FollowMe);
+ EMPTY(ContactInfantry);
+ EMPTY(ContactVehicle);
+ EMPTY(ContactFortification);
+ EMPTY(NeedAmmo);
+ EMPTY(ACECheck);
+ EMPTY(StatusGreen);
+ EMPTY(StatusYellow);
+ EMPTY(StatusRed);
+ EMPTY(StatusBlack);
+ EMPTY(AskFirePermission);
+ EMPTY(ClearBackblast);
+ EMPTY(BackblastClear);
+ EMPTY(RocketFire);
+ EMPTY(Unconscious);
+ EMPTY(ThrowGrenade);
+ EMPTY(ThrowSmoke);
+ EMPTY(ThrowChemlight);
+ EMPTY(ThrowIR);
+};
\ No newline at end of file
diff --git a/addons/chatwheel/CfgEventHandlers.hpp b/addons/chatwheel/CfgEventHandlers.hpp
new file mode 100644
index 0000000..2fb9717
--- /dev/null
+++ b/addons/chatwheel/CfgEventHandlers.hpp
@@ -0,0 +1,23 @@
+class Extended_PreStart_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
+ };
+};
+
+class Extended_PreInit_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
+ };
+};
+
+class Extended_PostInit_EventHandlers {
+ class ADDON {
+ clientInit = QUOTE(call COMPILE_SCRIPT(XEH_postInitClient));
+ };
+};
+
+class Extended_FiredBIS_EventHandlers {
+ class CAManBase {
+ ADDON = QUOTE(call FUNC(fired));
+ };
+};
\ No newline at end of file
diff --git a/addons/chatwheel/CfgHints.hpp b/addons/chatwheel/CfgHints.hpp
new file mode 100644
index 0000000..b24b364
--- /dev/null
+++ b/addons/chatwheel/CfgHints.hpp
@@ -0,0 +1,14 @@
+class CfgHints {
+ class GVAR(UserGuide) {
+ displayName = CSTRING(hint_UserGuide_Name);
+
+ class KeybindsAndOptions {
+ displayName = QUOTE(MOD_NAME);
+ displayNameShort = CSTRING(hint_UserGuide_KeybindsAndOptions_DisplayNameShort);
+ description = CSTRING(hint_UserGuide_KeybindsAndOptions_Description);
+
+ image = "\a3\ui_f\data\gui\cfg\hints\Miss_icon_ca.paa";
+ noImage = "false";
+ };
+ };
+};
\ No newline at end of file
diff --git a/addons/chatwheel/CfgMagazines.hpp b/addons/chatwheel/CfgMagazines.hpp
new file mode 100644
index 0000000..77d035a
--- /dev/null
+++ b/addons/chatwheel/CfgMagazines.hpp
@@ -0,0 +1,19 @@
+class CfgMagazines {
+ class CA_Magazine;
+ class HandGrenade: CA_Magazine {
+ GVARMAIN(grenadeType) = CSTRING(grenadeType_Grenade);
+ };
+
+ class SmokeShell: HandGrenade {
+ GVARMAIN(grenadeType) = CSTRING(grenadeType_Smoke);
+ };
+
+ class Chemlight_green: SmokeShell {
+ GVARMAIN(grenadeType) = CSTRING(grenadeType_Chemlight);
+ };
+
+ class B_IR_Grenade: CA_Magazine {
+ GVARMAIN(grenadeType) = CSTRING(grenadeType_IR);
+ GVARMAIN(grenadeLocalized) = CSTRING(grenadeType_IR_localized);
+ };
+};
\ No newline at end of file
diff --git a/addons/chatwheel/CfgUIGrids.hpp b/addons/chatwheel/CfgUIGrids.hpp
new file mode 100644
index 0000000..1b7a194
--- /dev/null
+++ b/addons/chatwheel/CfgUIGrids.hpp
@@ -0,0 +1,28 @@
+class CfgUIGrids {
+ class IGUI {
+ class Variables {
+ class GVAR(Grid_ChatWheel) {
+ displayName = CSTRING(hud_ChatWheel);
+ description = CSTRING(hudDescription_ChatWheel);
+ preview = QPATHTOF(data\GUI\Cfg\UIGrids\grid_ChatWheel_ca.paa); // TODO: Move preview text by ~3 pixels (OCD)
+ saveToProfile[] = {IGUI_SAVEALL};
+ };
+ };
+
+ class Presets {
+ class Arma3 {
+ class Variables {
+ GVAR(Grid_ChatWheel)[] = { {
+ QUOTE(GUI_GRID_CENTER_X),
+ QUOTE(GUI_GRID_CENTER_Y),
+ QUOTE(5 * GUI_GRID_CENTER_W),
+ QUOTE(10 * GUI_GRID_CENTER_H)
+ },
+ QUOTE(GUI_GRID_CENTER_W),
+ QUOTE(GUI_GRID_CENTER_H)
+ };
+ };
+ };
+ };
+ };
+};
\ No newline at end of file
diff --git a/addons/chatwheel/RscTitles.hpp b/addons/chatwheel/RscTitles.hpp
new file mode 100644
index 0000000..9cda79a
--- /dev/null
+++ b/addons/chatwheel/RscTitles.hpp
@@ -0,0 +1,5 @@
+#include "ui\BaseControls.hpp"
+
+class RscTitles {
+ #include "ui\RscChatWheel.hpp"
+};
\ No newline at end of file
diff --git a/addons/chatwheel/XEH_PREP.hpp b/addons/chatwheel/XEH_PREP.hpp
new file mode 100644
index 0000000..f8bdb81
--- /dev/null
+++ b/addons/chatwheel/XEH_PREP.hpp
@@ -0,0 +1,17 @@
+PREP(addMessage);
+PREP(canUseVoiceLine);
+PREP(closeChatWheel);
+PREP(findVoiceTags);
+PREP(fired);
+PREP(handleScroll);
+PREP(openChatWheel);
+PREP(playLocalSound);
+PREP(populateChatWheel);
+PREP(processTags);
+PREP(removeMessage);
+PREP(scanConfig);
+PREP(selectMessage);
+PREP(sendMessage);
+PREP(toggleChatWheel);
+PREP(unconscious);
+PREP(useVoiceLine);
\ No newline at end of file
diff --git a/addons/chatwheel/XEH_postInitClient.sqf b/addons/chatwheel/XEH_postInitClient.sqf
new file mode 100644
index 0000000..b5dd898
--- /dev/null
+++ b/addons/chatwheel/XEH_postInitClient.sqf
@@ -0,0 +1,12 @@
+#include "script_component.hpp"
+
+if !(profileNamespace getVariable [QGVAR(seenFirstUseHint), false]) then {
+ [[QGVAR(UserGuide), "KeybindsAndOptions"], 15, "", 35, "", true, true, true] call BIS_fnc_advHint;
+ profileNamespace setVariable [QGVAR(seenFirstUseHint), true];
+};
+
+["CBA_settingsInitialized", {
+ if (ADDON_LOADED(ace_medical)) then {
+ ["ace_unconscious", LINKFUNC(unconscious)] call CBA_fnc_addEventHandler;
+ };
+}] call CBA_fnc_addEventHandler;
\ No newline at end of file
diff --git a/addons/ChatWheel/XEH_preInit.sqf b/addons/chatwheel/XEH_preInit.sqf
similarity index 52%
rename from addons/ChatWheel/XEH_preInit.sqf
rename to addons/chatwheel/XEH_preInit.sqf
index f46abd2..d6bb709 100644
--- a/addons/ChatWheel/XEH_preInit.sqf
+++ b/addons/chatwheel/XEH_preInit.sqf
@@ -1,6 +1,10 @@
#include "script_component.hpp"
+PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
+PREP_RECOMPILE_END;
+
+private _category = [QUOTE(MOD_NAME), QUOTE(COMPONENT_BEAUTIFIED)];
#include "initSettings.inc.sqf"
#include "initKeybinds.inc.sqf"
\ No newline at end of file
diff --git a/addons/chatwheel/XEH_preStart.sqf b/addons/chatwheel/XEH_preStart.sqf
new file mode 100644
index 0000000..3d7d26f
--- /dev/null
+++ b/addons/chatwheel/XEH_preStart.sqf
@@ -0,0 +1,5 @@
+#include "script_component.hpp"
+
+#include "XEH_PREP.hpp"
+
+[] call FUNC(scanConfig);
\ No newline at end of file
diff --git a/addons/chatwheel/config.cpp b/addons/chatwheel/config.cpp
new file mode 100644
index 0000000..14c73fd
--- /dev/null
+++ b/addons/chatwheel/config.cpp
@@ -0,0 +1,25 @@
+#include "script_component.hpp"
+
+class CfgPatches {
+ class ADDON {
+ author = AUTHOR;
+ authors[] = {"DartRuffian"};
+ name = COMPONENT_NAME;
+ requiredVersion = REQUIRED_VERSION;
+ requiredAddons[] = {
+ "cwr_common"
+ };
+ units[] = {};
+ weapons[] = {};
+ VERSION_CONFIG;
+ };
+};
+
+#include "CfgEventHandlers.hpp"
+#include "CfgMagazines.hpp"
+#include "CfgUIGrids.hpp"
+#include "RscTitles.hpp"
+#include "CfgHints.hpp"
+#include "CWR_ChatWheel_Messages.hpp"
+#include "CWR_ChatWheel_Tags.hpp"
+#include "CWR_ChatWheel_VoiceLines.hpp"
\ No newline at end of file
diff --git a/addons/chatwheel/data/GUI/Cfg/UIGrids/grid_ChatWheel_ca.paa b/addons/chatwheel/data/GUI/Cfg/UIGrids/grid_ChatWheel_ca.paa
new file mode 100644
index 0000000..c968fce
Binary files /dev/null and b/addons/chatwheel/data/GUI/Cfg/UIGrids/grid_ChatWheel_ca.paa differ
diff --git a/addons/chatwheel/defines.hpp b/addons/chatwheel/defines.hpp
new file mode 100644
index 0000000..1183eda
--- /dev/null
+++ b/addons/chatwheel/defines.hpp
@@ -0,0 +1,4 @@
+#define IDD_CHATWHEEL_MAIN 500
+#define IDC_CHATWHEEL_MESSAGES 501
+
+#define REGEX_LOWERCASE_TAGS "\[.*?\]", "\L$&"
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_addMessage.sqf b/addons/chatwheel/functions/fnc_addMessage.sqf
new file mode 100644
index 0000000..dcaa1ab
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_addMessage.sqf
@@ -0,0 +1,48 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Adds a message to the Chat Wheel menu.
+ *
+ * Arguments:
+ * 0: Unique identifier for the message
+ * 1: Text displayed in the Chat Wheel
+ * 2: The message sent when this option is selected
+ * 3: The order to sort the message by (optional, default: -1 will put message at the end of the list).
+ * -1 will result in an order that is the number of current elements + 100.
+ * 4: Overwrite existing message if present (optional, default: false)
+ *
+ * Return Value:
+ * True on success, false otherwise
+ *
+ * Example:
+ * ["Custom1", "Custom 1", "This is my custom message", 10] call cwr_chatwheel_fnc_addMessage;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_key", "", [""]],
+ ["_displayName", "", [""]],
+ ["_message", "", [""]],
+ ["_order", -1, [0]],
+ ["_overwrite", false, [false]]
+];
+TRACE_5("fnc_addMessage",_key,_displayName,_message,_order,_overwrite);
+
+if (_key == "" or {_displayName == ""} or {_message = ""}) exitWith { false };
+
+private _messageList = uiNamespace getVariable [QGVAR(messages), createHashMap];
+
+if (_key in _messageList and {!_overwrite}) exitWith {false};
+
+if (_order == -1) then {
+ _order = count _messageList;
+};
+
+_messageList insert [[_key, [
+ _displayName,
+ _message,
+ _order
+]]];
+
+true;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_canUseVoiceLine.sqf b/addons/chatwheel/functions/fnc_canUseVoiceLine.sqf
new file mode 100644
index 0000000..50f3fc9
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_canUseVoiceLine.sqf
@@ -0,0 +1,25 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Determines if a unit can use a voice line.
+ *
+ * Arguments:
+ * 0: Unit
+ *
+ * Return Value:
+ * True if unit can say a voice line, otherwise false
+ *
+ * Example:
+ * player call cwr_chatwheel_fnc_canUseVoiceLine;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_unit", objNull, [objNull]]
+];
+TRACE_1("fnc_canUseVoiceLine",_unit);
+
+private _lastUsedVoice = _unit getVariable [QGVAR(lastUsedVoice), -GVAR(voice_cooldown)];
+
+(CBA_missionTime - _lastUsedVoice) >= GVAR(voice_cooldown);
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_closeChatWheel.sqf b/addons/chatwheel/functions/fnc_closeChatWheel.sqf
new file mode 100644
index 0000000..02286b0
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_closeChatWheel.sqf
@@ -0,0 +1,29 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Closes the Chat Wheel menu.
+ *
+ * Arguments:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call cwr_chatwheel_fnc_closeChatWheel;
+ *
+ * Public: Yes
+ */
+
+params [];
+TRACE_1("fnc_closeChatWheel",nil);
+
+private _display = uiNamespace getVariable ["CWR_RscChatWheel", displayNull];
+if (isNull _display) exitWith {
+ WARNING("Attempted to close Chat Wheel when not open.");
+};
+
+QGVAR(layer_chatWheel) cutFadeOut 0.5;
+[QGVAR(menuToggled), false] call CBA_fnc_localEvent;
+
+nil;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_findVoiceTags.sqf b/addons/chatwheel/functions/fnc_findVoiceTags.sqf
new file mode 100644
index 0000000..9ed61cd
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_findVoiceTags.sqf
@@ -0,0 +1,25 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Finds and returns all voice line tags in a message. Voice line tags are tags that begin with "vl-". A voice line tag must match the regex pattern: "\[vl-[A-z0-9]+\]/g" to be recognized and processed properly.
+ *
+ * Arguments:
+ * 0: The message to scan
+ *
+ * Return Value:
+ * Array of all voice line tags
+ *
+ * Example:
+ * "[vl-voiceLine]A message[vl-voiceLine2]" call cwr_chatwheel_fnc_findVoiceTags;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_message", "", [""]]
+];
+TRACE_1("fnc_findVoiceTags",_message);
+
+private _tags = _message regexFind ["\[vl-[A-z0-9]+\]/g"];
+_tags = _tags apply { _x#0#0 };
+_tags;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_fired.sqf b/addons/chatwheel/functions/fnc_fired.sqf
new file mode 100644
index 0000000..b6bd1d2
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_fired.sqf
@@ -0,0 +1,45 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Sends a message for a unit throwing a grenade. Some parameters are unused and are carried over from the vanilla Fired and ace_firedPlayer event handlers. These can be safely ignored by passing an empty string for their value.
+ *
+ * Arguments:
+ * 0: The unit throwing the grenade
+ * 1: Weapon class name
+ * 2: Muzzle class name (unused)
+ * 3: Mode class name (unused)
+ * 4: Ammo class name (unused)
+ * 5: Magazine class name
+ *
+ * Return Value:
+ * None
+ *
+ * Public: No
+ */
+
+params ["_unit", "_weapon", "", "", "", "_magazine"];
+TRACE_3("fnc_fired",_unit,_weapon,_magazine);
+
+if (!GVAR(autoMessages_enabled) or
+ {!GVAR(autoMessages_enabledGrenades)} or
+ {!isThrowable _magazine} or
+ {_unit isNotEqualTo ([] call CBA_fnc_currentUnit)}
+) exitWith {};
+
+
+private _magazineConfig = configFile >> "CfgMagazines" >> _magazine;
+private _grenadeType = getText (_magazineConfig >> QGVARMAIN(grenadeType));
+private _grenadeLocalized = getText (_magazineConfig >> QGVARMAIN(grenadeLocalized));
+
+if (_grenadeType == "") then {
+ _grenadeType = "Grenade";
+};
+
+if (_grenadeLocalized == "") then {
+ _grenadeLocalized = _grenadeType;
+};
+
+private _message = format [LLSTRING(message_GrenadeThrown), _grenadeType, _grenadeLocalized];
+[_message, _unit, "side-local", GVAR(voice_radius)] call FUNC(sendMessage);
+
+nil;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_handleScroll.sqf b/addons/chatwheel/functions/fnc_handleScroll.sqf
new file mode 100644
index 0000000..08d0ade
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_handleScroll.sqf
@@ -0,0 +1,35 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Logic for handling mouse wheel scrolling to select different options in the Chat Wheel.
+ *
+ * Arguments:
+ * 0: True to scroll up one item, false to scroll down one item (optional, default: false)
+ *
+ * Return Value:
+ * The selected index after scrolling
+ *
+ * Example:
+ * true call cwr_chatwheel_fnc_handleScroll
+ *
+ * Public: No
+ */
+
+params [["_scroll", false, [false]]];
+TRACE_1("fnc_handleScroll",_scroll);
+
+if (visibleMap) exitWith {};
+
+private _display = uiNamespace getVariable ["CWR_RscChatWheel", displayNull];
+private _messagesCtrl = _display displayCtrl IDC_CHATWHEEL_MESSAGES;
+private _selectedIndex = lbCurSel _messagesCtrl;
+
+if (_scroll) then {
+ _selectedIndex = _selectedIndex + 1;
+} else {
+ _selectedIndex = _selectedIndex - 1;
+};
+
+_selectedIndex = CLAMP(_selectedIndex,0,lbSize _messagesCtrl);
+_messagesCtrl lbSetCurSel _selectedIndex;
+lbCurSel _messagesCtrl;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_openChatWheel.sqf b/addons/chatwheel/functions/fnc_openChatWheel.sqf
new file mode 100644
index 0000000..730fe11
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_openChatWheel.sqf
@@ -0,0 +1,29 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Opens the Chat Wheel menu, but does not populate it with any data.
+ *
+ * Arguments:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call cwr_chatwheel_fnc_openChatWheel;
+ *
+ * Public: Yes
+ */
+
+TRACE_1("fnc_openChatWheel",nil);
+
+private _display = uiNamespace getVariable ["CWR_RscChatWheel", displayNull];
+if (!isNull _display) exitWith {
+ WARNING("Attempted to open Chat Wheel when already open.");
+};
+
+(QGVAR(layer_chatWheel) call BIS_fnc_rscLayer) cutRsc ["CWR_RscChatWheel", "PLAIN", -1, false];
+_display = uiNamespace getVariable ["CWR_RscChatWheel", displayNull];
+private _messagesCtrl = _display displayCtrl IDC_CHATWHEEL_MESSAGES;
+
+[QGVAR(menuToggled), [true]] call CBA_fnc_localEvent;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_playLocalSound.sqf b/addons/chatwheel/functions/fnc_playLocalSound.sqf
new file mode 100644
index 0000000..f8ff364
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_playLocalSound.sqf
@@ -0,0 +1,35 @@
+#include "..\script_component.hpp"
+/*
+ * Author: Leopard20
+ * Edited By DartRuffian
+ * Plays a sound local to the current system.
+ *
+ * Arguments:
+ * 0: File path to sound
+ * 1: Sound position in format PositionASL
+ * 2: Base volume (optional, default: 1)
+ * 3: Base pitch (optional, default: 1)
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * ["file.wss", player] call cwr_chatwheel_fnc_playLocalSound;
+ *
+ * Public: No
+ */
+
+params [
+ ["_file", "", [""]],
+ ["_positionASL", [0, 0, 0], [[]], 3],
+ ["_volume", 1, [0]],
+ ["_pitch", 1, [0]]
+];
+TRACE_4("fnc_playLocalSound",_file,_positionASL,_volume,_pitch);
+
+// Addon check for when this function is remoteExecCall'd
+if (ADDON_LOADED(ADDON) and {GVAR(voice_enabled)}) then {
+ playSound3D [_file, objNull, false, _positionASL, GVAR(voice_volume) * _volume, _pitch, 0, 0, true];
+};
+
+nil;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_populateChatWheel.sqf b/addons/chatwheel/functions/fnc_populateChatWheel.sqf
new file mode 100644
index 0000000..9a124f8
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_populateChatWheel.sqf
@@ -0,0 +1,44 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Takes messages stored in CWR_ChatWheel_messages from uiNamespace and populates the message listbox control. If the data to populate the list with is empty, the saved message list will be used instead.
+ *
+ * Arguments:
+ * 0: Message data to populate the Chat Wheel (optional, default: message list)
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call cwr_chatwheel_fnc_populateChatWheel;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_lbData", createHashMap, [createHashMap]]
+];
+TRACE_1("fnc_populateChatWheel",_lbData);
+
+if (count _lbData isEqualTo 0) then {
+ _lbData = uiNamespace getVariable [QGVAR(messages), createHashMap];
+};
+
+[{
+ (!isNull (uiNamespace getVariable ["CWR_RscChatWheel", displayNull]))
+}, {
+ params ["_lbData"];
+ private _display = uiNamespace getVariable ["CWR_RscChatWheel", displayNull];
+ private _messagesCtrl = _display displayCtrl IDC_CHATWHEEL_MESSAGES;
+
+ {
+ _y params ["_displayName", "_message", "_order"];
+ private _index = _messagesCtrl lbAdd _displayName;
+ _messagesCtrl lbSetValue [_index, _order];
+ _messagesCtrl lbSetData [_index, _x];
+ } forEach _lbData;
+
+ _messagesCtrl lbSortBy ["VALUE"];
+
+ [{ _this lbSetCurSel 0; }, _messagesCtrl] call CBA_fnc_execNextFrame;
+}, [_lbData]] call CBA_fnc_waitUntilAndExecute;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_processTags.sqf b/addons/chatwheel/functions/fnc_processTags.sqf
new file mode 100644
index 0000000..d43b64b
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_processTags.sqf
@@ -0,0 +1,46 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Processes a message for "simple" tags. A simple tag does not require user input and is text replaced with a code output.
+ * E.g. [weapon] is replaced with the displayName of the author's current held weapon.
+ *
+ * Arguments:
+ * 0: Unit
+ * 1: The message to process
+ *
+ * Return Value:
+ * The processed message
+ *
+ * Example:
+ * [player, "A message, optionally with [tags]"] call cwr_chatwheel_fnc_processTags;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_author", objNull, [objNull]],
+ ["_message", "", [""]]
+];
+TRACE_2("fnc_processTags",_author,_message);
+
+private _tagsList = uiNamespace getVariable [QGVAR(tags), createHashMap];
+_message = _message regexReplace [REGEX_LOWERCASE_TAGS]; // lowercase everything in [brackets]
+
+{
+ private _tag = format ["[%1]", toLowerANSI _x];
+ _y params ["", "_statement"];
+
+ if (_statement isNotEqualTo {}) then {
+ _message = [_message, _tag, _author call _statement] call EFUNC(common,stringReplace);
+ };
+} forEach _tagsList;
+
+private _voiceLine = (_message call FUNC(findVoiceTags)) select 0;
+if (_author call FUNC(canUseVoiceLine)) then {
+ private _voiceLineClass = _voiceLine select [4, count _voiceLine - 5];
+
+ [_author, _voiceLineClass] call FUNC(useVoiceLine);
+};
+_message = [_message, _voiceLine, ""] call EFUNC(common,stringReplace);
+
+_message;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_removeMessage.sqf b/addons/chatwheel/functions/fnc_removeMessage.sqf
new file mode 100644
index 0000000..0a07a0f
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_removeMessage.sqf
@@ -0,0 +1,26 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Removes a message from the Chat Wheel menu.
+ *
+ * Arguments:
+ * 0: Unique identifier of the message
+ *
+ * Return Value:
+ * True on success, false otherwise
+ *
+ * Example:
+ * "Custom1" call cwr_chatwheel_fnc_removeMessage;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_key", "", [""]]
+];
+TRACE_1("fnc_removeMessage",_key);
+
+private _messageList = uiNamespace getVariable [QGVAR(messages), createHashMap];
+private _deleted = _messageList deleteAt _key;
+
+!isNil "_deleted";
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_scanConfig.sqf b/addons/chatwheel/functions/fnc_scanConfig.sqf
new file mode 100644
index 0000000..afe264b
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_scanConfig.sqf
@@ -0,0 +1,65 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Loads messages, tags, and voice line classes to HashMaps in uiNamespace.
+ *
+ * Arguments:
+ * 0: Reload from config (optional, default: false)
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call cwr_chatwheel_fnc_scanConfig;
+ *
+ * Public: No
+ */
+
+params [
+ ["_reload", false]
+];
+TRACE_1("fnc_scanConfig",_reload);
+
+private _messageConfig = configProperties [configFile >> QGVAR(messages)];
+private _messageList = uiNamespace getVariable [QGVAR(messages), createHashMap];
+
+if (_reload or {_messageList isEqualTo createHashMap}) then {
+ _messageList = createHashMap;
+ {
+ _messageList insert [[configName _x, [
+ getText (_x >> "displayName"),
+ getText (_x >> "message"),
+ getNumber (_x >> "order")
+ ]]];
+ } forEach _messageConfig;
+
+ uiNamespace setVariable [QGVAR(messages), _messageList];
+};
+
+private _voiceLineConfig = configProperties [configFile >> QGVAR(voiceLines)];
+private _voiceLineList = uiNamespace getVariable [QGVAR(voiceLines), createHashMap];
+
+if (_reload or {_voiceLineList isEqualTo createHashMap}) then {
+ _voiceLineList = createHashMap;
+ {
+ _voiceLineList insert [[configName _x, getArray (_x >> "voiceLines")]];
+ } forEach _voiceLineConfig;
+
+ uiNamespace setVariable [QGVAR(voiceLines), _voiceLinesList];
+};
+
+_tagsConfig = configProperties [configFile >> QGVAR(tags)];
+_tagsList = uiNamespace getVariable [QGVAR(tags), createHashMap];
+
+if (_reload or {_tagsList isEqualTo createHashMap}) then {
+ _tagsList = createHashMap;
+ {
+ _tagsList insert [[configName _x, [
+ getText (_x >> "description"),
+ compile (getText (_x >> "statement")),
+ getText (_x >> "example")
+ ]]];
+ } forEach _tagsConfig;
+
+ uiNamespace setVariable [QGVAR(tags), _tagsList];
+};
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_selectMessage.sqf b/addons/chatwheel/functions/fnc_selectMessage.sqf
new file mode 100644
index 0000000..99caa91
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_selectMessage.sqf
@@ -0,0 +1,35 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Selects a message from the Chat Wheel to then be processed and sent.
+ *
+ * Arguments:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call cwr_chatwheel_fnc_selectMessage;
+ *
+ * Public: No
+ */
+
+TRACE_1("fnc_selectMessage",nil);
+
+private _display = uiNamespace getVariable ["CWR_RscChatWheel", displayNull];
+private _messagesCtrl = _display displayCtrl IDC_CHATWHEEL_MESSAGES;
+
+if (isNull _display or {isNull _messagesCtrl}) exitWith {
+ WARNING("Attempted to send message while display was not open");
+};
+
+private _selectedIndex = lbCurSel _messagesCtrl;
+private _className = _messagesCtrl lbData _selectedIndex;
+
+private _messageList = uiNamespace getVariable [QGVAR(messages), createHashMap];
+(_messageList get _className) params ["", "_message"];
+
+[_message, [] call CBA_fnc_currentUnit, "side-local", GVAR(voice_radius)] call FUNC(sendMessage);
+
+nil;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_sendMessage.sqf b/addons/chatwheel/functions/fnc_sendMessage.sqf
new file mode 100644
index 0000000..92d69d7
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_sendMessage.sqf
@@ -0,0 +1,56 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Takes a message and author, processes the tags in the message, and sends it to the given channel.
+ *
+ * Arguments:
+ * 0: The message to send, optionally with [tags]
+ * 1: The author of the message (optional, default: player)
+ * 2: The channel / target to send the message in (optional, default: "side")
+ * - Can be one of:
+ * 1: "side" - Sends message in side channel on author's side.
+ * 2: "group" - Sends message in group channel in author's group.
+ * 3: "side-local" - Sends message in side chat, but only displays to player's within a given distance. Fourth parameter is range in meters.
+ * 4: "global" - Sends message in global chat
+ * 3: Target data (optional, default: nil)
+ * - This parameter will be used differently for each channel or target.
+ *
+ * Return Value:
+ * None
+ *
+ * Examples:
+ * ["A message, optionally with [tags]"] call cwr_chatwheel_fnc_sendMessage;
+ * ["A local message", player, "side-local", 10] call cwr_chatwheel_fnc_sendMessage;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_rawMessage", "", [""]],
+ ["_author", objNull, [objNull]],
+ ["_channel", "side", [""]],
+ ["_targetData", nil, []]
+];
+TRACE_4("fnc_sendMessage",_rawMessage,_author,_channel,_targetData);
+
+if (_rawMessage isEqualTo "") exitWith {};
+
+if (isNull _author) then {
+ _author = [] call CBA_fnc_currentUnit;
+};
+
+_message = [_author, _rawMessage] call FUNC(processTags);
+
+private _target = switch (_channel) do {
+ case "group": {["groupChat", group _author]};
+ case "side-local": {
+ private _nearbyPlayers = [ASLToAGL getPosASL _author, _targetData] call EFUNC(common,getNearbyPlayers);
+ ["sideChat", _nearbyPlayers];
+ };
+ case "global": {["globalChat", 0]};
+ default {["sideChat", side _author]};
+};
+
+[_author, _message] remoteExecCall _target;
+[QGVAR(onMessage), [_author, _message, _rawMessage]] call CBA_fnc_localEvent;
+INFO_2("%1 is sending message: %2",_author,_message);
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_toggleChatWheel.sqf b/addons/chatwheel/functions/fnc_toggleChatWheel.sqf
new file mode 100644
index 0000000..00f9e92
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_toggleChatWheel.sqf
@@ -0,0 +1,30 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Opens or closes the Chat Wheel, based on its current state.
+ *
+ * Arguments:
+ * None
+ *
+ * Return Value:
+ * True if opened, false otherwise
+ *
+ * Example:
+ * [] call cwr_chatwheel_fnc_toggleChatWheel;
+ *
+ * Public: Yes
+ */
+
+TRACE_1("fnc_toggleChatWheel",nil);
+
+private _display = uiNamespace getVariable ["CWR_RscChatWheel", displayNull];
+private _opened = false;
+
+if (isNull _display) then {
+ [] call FUNC(openChatWheel);
+ _opened = true;
+} else {
+ [] call FUNC(closeChatWheel);
+};
+
+_opened;
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_unconscious.sqf b/addons/chatwheel/functions/fnc_unconscious.sqf
new file mode 100644
index 0000000..bd208ae
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_unconscious.sqf
@@ -0,0 +1,28 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Sends a message for a unit falling unconscious, only works for ACE Medical.
+ *
+ * Arguments:
+ * 0: The unit falling unconscious or waking up
+ * 1: Unconscious state
+ *
+ * Return Value:
+ * None
+ *
+ * Examples:
+ * ["ace_unconscious", cwr_chatwheel_fnc_unconscious] call CBA_fnc_addEventHandler;
+ *
+ * Public: No
+ */
+
+params ["_unit", "_state"];
+TRACE_2("fnc_unconscious",_unit,_state);
+
+if (!GVAR(autoMessages_enabledUnconscious) or {!_state} or {isNull _unit}) exitWith {};
+
+private _positionAGL = ASLToAGL getPosASL _unit;
+private _nearbyPlayers = [_positionAGL, GVAR(voice_radius)] call EFUNC(common,getNearbyPlayers) select {_x call ace_common_fnc_isAwake};
+_nearbyPlayers = [_positionAGL, _nearbyPlayers] call EFUNC(common,sortByDistance);
+
+[format [LLSTRING(message_Unconscious), name _unit], _nearbyPlayers#0, "side-local", GVAR(voice_radius)] call FUNC(sendMessage);
\ No newline at end of file
diff --git a/addons/chatwheel/functions/fnc_useVoiceLine.sqf b/addons/chatwheel/functions/fnc_useVoiceLine.sqf
new file mode 100644
index 0000000..dcb64c0
--- /dev/null
+++ b/addons/chatwheel/functions/fnc_useVoiceLine.sqf
@@ -0,0 +1,37 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Plays a voice line from a given unit.
+ *
+ * Arguments:
+ * 0: Unit
+ * 1: Class name from CWR_ChatWheel_VoiceLines
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [player, "NeedMedic"] call cwr_chatwheel_fnc_useVoiceLine;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_unit", objNull, [objNull]],
+ ["_voiceLineClass", "", [""]]
+];
+TRACE_2("fnc_useVoiceLine",_unit,_voiceLineClass);
+
+private _voiceLines = getArray (configFile >> QGVAR(VoiceLines) >> _voiceLineClass >> "voiceLines");
+_voiceLines = _voiceLines select { _x select 0 != "" };
+if (_voiceLines isEqualTo []) exitWith {};
+
+(selectRandom _voiceLines) params ["_file", "_volume", "_pitch"];
+
+private _nearbyPlayers = [ASLToAGL getPosASL _unit, GVAR(voice_radius)] call EFUNC(common,getNearbyPlayers);
+private _positionASL = getPosASL _unit;
+
+[_file, _positionASL, _volume, _pitch] remoteExecCall [QFUNC(playLocalSound), _nearbyPlayers];
+_unit setVariable [QGVAR(lastUsedVoice), CBA_missionTime];
+
+nil;
\ No newline at end of file
diff --git a/addons/chatwheel/initKeybinds.inc.sqf b/addons/chatwheel/initKeybinds.inc.sqf
new file mode 100644
index 0000000..7e6b14e
--- /dev/null
+++ b/addons/chatwheel/initKeybinds.inc.sqf
@@ -0,0 +1,36 @@
+#include "\z\cwr\addons\main\data\hpp\defineDIKCodes.inc"
+
+[
+ _category, QGVAR(key_openMenu),
+ [LLSTRING(key_openMenu), LLSTRING(keyDescription_openMenu)], {
+ if ([] call FUNC(toggleChatWheel)) then {
+ [] call FUNC(populateChatWheel);
+ };
+ }
+] call CBA_fnc_addKeybind;
+
+[
+ _category, QGVAR(key_selectMessage),
+ [LLSTRING(key_selectMessage), LLSTRING(keyDescription_selectMessage)],
+ {
+ private _display = uiNamespace getVariable ["CWR_RscChatWheel", displayNull];
+ if (!isNull _display) then {
+ [] call FUNC(selectMessage);
+ [] call FUNC(closeChatWheel);
+ };
+ }, {}, [DIK_SPACE, false, false, false]
+] call CBA_fnc_addKeybind;
+
+[
+ _category, QGVAR(key_scrollUp),
+ [LLSTRING(key_scrollUp), LLSTRING(keyDescription_scrollUp)], {
+ GVAR(useInvertedScrolling) call FUNC(handleScroll);
+ }, {}, [DIK_MOUSEUP, false, false, false]
+] call CBA_fnc_addKeybind;
+
+[
+ _category, QGVAR(key_scrollDown),
+ [LLSTRING(key_scrollDown), LLSTRING(keyDescription_scrollDown)], {
+ !GVAR(useInvertedScrolling) call FUNC(handleScroll);
+ }, {}, [DIK_MOUSEDOWN, false, false, false]
+] call CBA_fnc_addKeybind;
\ No newline at end of file
diff --git a/addons/chatwheel/initSettings.inc.sqf b/addons/chatwheel/initSettings.inc.sqf
new file mode 100644
index 0000000..8e01889
--- /dev/null
+++ b/addons/chatwheel/initSettings.inc.sqf
@@ -0,0 +1,115 @@
+[
+ QGVAR(useInvertedScrolling), "CHECKBOX",
+ [LLSTRING(setting_useInvertedScrolling), LLSTRING(settingDescription_useInvertedScrolling)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_controls)],
+ false
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(customMessages_one), "EDITBOX",
+ [LLSTRING(setting_customMessages_one), LLSTRING(settingDescription_customMessages)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_customMessages)],
+ "", 0, {
+ if (_this != "") then {
+ private _name = _this call EFUNC(common,truncate);
+ ["UserCustom1", _name, _this, -1, true] call FUNC(addMessage);
+ } else {
+ "UserCustom1" call FUNC(removeMessage);
+ };
+ }
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(customMessage_two), "EDITBOX",
+ [LLSTRING(setting_customMessages_two), LLSTRING(settingDescription_customMessages)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_customMessages)],
+ "", 0, {
+ if (!(_this isEqualTo "")) then {
+ private _name = _this call EFUNC(common,truncate);
+ ["UserCustom2", _name, _this, -1, true] call FUNC(addMessage);
+ } else {
+ "UserCustom2" call FUNC(removeMessage);
+ };
+ }
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(customMessage_three),
+ "EDITBOX",
+ [LLSTRING(setting_customMessages_three), LLSTRING(settingDescription_customMessages)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_customMessages)],
+ "", 0, {
+ if (!(_this isEqualTo "")) then {
+ private _name = _this call EFUNC(common,truncate);
+ ["UserCustom3", _name, _this, -1, true] call FUNC(addMessage);
+ } else {
+ "UserCustom3" call FUNC(removeMessage);
+ };
+ }
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(customMessage_four),
+ "EDITBOX",
+ [LLSTRING(setting_customMessages_four), LLSTRING(settingDescription_customMessages)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_customMessages)],
+ "", 0, {
+ if (!(_this isEqualTo "")) then {
+ private _name = _this call EFUNC(common,truncate);
+ ["UserCustom4", _name, _this, -1, true] call FUNC(addMessage);
+ } else {
+ "UserCustom4" call FUNC(removeMessage);
+ };
+ }
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(autoMessages_enabled), "CHECKBOX",
+ [LLSTRING(setting_autoMessages_enabled), LLSTRING(settingDescription_autoMessages_enabled)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_autoMessages)],
+ true, 0
+] call CBA_fnc_addSetting;
+
+if (ADDON_LOADED(ace_medical)) then {
+ [
+ QGVAR(autoMessages_enabledUnconscious), "CHECKBOX",
+ [LLSTRING(setting_autoMessages_enabledUnconscious), LLSTRING(settingDescription_autoMessages_enabledUnconscious)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_autoMessages)],
+ true, 1
+ ] call CBA_fnc_addSetting;
+};
+
+[
+ QGVAR(autoMessages_enabledGrenades), "CHECKBOX",
+ [LLSTRING(setting_autoMessages_enabledGrenades), LLSTRING(settingDescription_autoMessages_enabledGrenades)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_autoMessages)],
+ true, 1
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(voice_enabled), "CHECKBOX",
+ [LLSTRING(setting_voice_enabled), LLSTRING(settingDescription_voice_enabled)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_voice)],
+ true, 0
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(voice_cooldown), "SLIDER",
+ [LLSTRING(setting_voice_cooldown), LLSTRING(settingDescription_voice_cooldown)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_voice)],
+ [0, 15, 3, 0], 1
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(voice_radius), "SLIDER",
+ [LLSTRING(setting_voice_radius), LLSTRING(settingDescription_voice_radius)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_voice)],
+ [10, 50, 30, 0], 1
+] call CBA_fnc_addSetting;
+
+[
+ QGVAR(voice_volume), "SLIDER",
+ [LLSTRING(setting_voice_volume), LLSTRING(settingDescription_voice_volume)],
+ [QUOTE(MOD_NAME), LLSTRING(settingCategory_voice)],
+ [0, 1, 1, 0, true]
+] call CBA_fnc_addSetting;
\ No newline at end of file
diff --git a/addons/chatwheel/script_component.hpp b/addons/chatwheel/script_component.hpp
new file mode 100644
index 0000000..efb8d72
--- /dev/null
+++ b/addons/chatwheel/script_component.hpp
@@ -0,0 +1,12 @@
+#define COMPONENT chatwheel
+#define COMPONENT_BEAUTIFIED Chat Wheel
+#include "\z\cwr\addons\main\script_mod.hpp"
+
+#define DEBUG_MODE_FULL
+#define DISABLE_COMPILE_CACHE
+
+#include "\z\cwr\addons\main\script_macros.hpp"
+#include "\z\cwr\addons\main\defines.hpp"
+#include "\a3\ui_f\hpp\defineCommonGrids.inc"
+#include "\a3\ui_f\hpp\defineCommonColors.inc"
+#include "defines.hpp"
\ No newline at end of file
diff --git a/addons/chatwheel/stringtable.xml b/addons/chatwheel/stringtable.xml
new file mode 100644
index 0000000..04b90b4
--- /dev/null
+++ b/addons/chatwheel/stringtable.xml
@@ -0,0 +1,383 @@
+
+
+
+
+ Chat Wheel - User Guide
+
+
+ Keybinds and Options
+
+
+ Thank you for using Chat Wheel Redux! To use this mod, check out the controls in Options → Controls → Configure Addons → Chat Wheel Redux. Options can be edited in Options → Addon Options → Chat Wheel Redux.
+
+
+
+ Chat Wheel
+
+
+ Message display for the Chat Wheel.
+
+
+
+
+
+
+ Select Message
+
+
+ Selects a message from the Chat Wheel.
+
+
+ Scroll Up
+
+
+ Scrolls up one option in the Chat Wheel.
+
+
+ Scroll Down
+
+
+ Scrolls down one option in the Chat Wheel.
+
+
+
+
+ Controls
+
+
+ Inverted Scrolling
+
+
+ Whether to invert the scrolling behavior for the Chat Wheel.
+
+
+
+ Custom Messages
+
+
+ Custom 1
+
+
+ Custom 2
+
+
+ Custom 3
+
+
+ Custom 4
+
+
+ Custom message that can be used in the Chat Wheel. Custom messages support [tags].
+
+
+
+ Automatic Messages
+
+
+ Enabled
+
+
+ Global setting for all automatic messages when certain actions are done.
+
+
+ Unconscious Messages
+
+
+ When a player goes unconscious, the closest conscious player will make a call out. Only works with ACE Medical.
+
+
+ Throwing Grenades
+
+
+ When a player throws a grenade, they will make a call out with the type of grenade (Grenade, smoke, etc.) and their bearing.
+
+
+
+ Voice Lines
+
+
+ Enabled
+
+
+ If enabled, messages will play the voice lines that can be added to them.
+
+
+ Cooldown
+
+
+ The minimum amount of time before another voice line can be played by a given player.
+
+
+ Radius
+
+
+ The radius in meters that voice lines can be heard from.
+
+
+ Volume
+
+
+ Volume multiplier for voice lines.
+
+
+
+
+ Call Medic
+
+
+ [vl-NeedMedic]I need a medic!
+
+
+
+ Call Help
+
+
+ [vl-NeedHelp]I need help!
+
+
+
+ Apologize
+
+
+ [vl-Sorry]Sorry!
+
+
+
+ Thank You
+
+
+ [vl-Thanks]Thank you!
+
+
+
+ Follow Me
+
+
+ [vl-FollowMe]Follow me!
+
+
+
+ Contact
+
+
+ [contact]
+
+
+
+ Need Ammo
+
+
+ [vl-NeedAmmo]I need ammo for my [weapon]!
+
+
+
+ ACE Check
+
+
+ [status]
+
+
+
+ Launcher
+
+
+ [launcher]
+
+
+
+
+ [vl-Unconscious]%1 is down!
+
+
+
+
+ [vl-Throw%1]%2 out, [bearing]!
+
+
+
+ Grenade
+
+
+ Smoke
+
+
+ Chemlight
+
+
+ IR
+
+
+ IR strobe
+
+
+ Flare
+
+
+ Flashbang
+
+
+ Incendiary
+
+
+ Incendiary grenade
+
+
+
+ Your current bearing.
+
+
+ 'I'm facing [tag]' → 'I'm facing 0'
+
+
+
+ Your current direction.
+
+
+ 'I'm facing [tag]' → 'I'm facing North'
+
+
+
+ The name of your currently held weapon.
+
+
+ 'I'm holding a [tag]' → 'I'm holding a MX 6.5mm'
+
+
+
+ Opens a new menu to select from 'Infantry', 'Vehicle', or 'Fortification'.
+
+
+ 'Contact, [tag]!' → 'Contact, infantry!'
+
+
+
+ Infantry
+
+
+ [vl-ContactInfantry]infantry
+
+
+ Vehicle
+
+
+ [vl-ContactVehicle]vehicle
+
+
+ Fortification
+
+
+ [vl-ContactFortification]fortification
+
+
+
+ Opens a new menu to select from 'Close', 'Medium', or 'Far'.
+
+
+ 'There's infantry [tag]' → 'There's infantry close'
+
+
+
+ Close
+
+
+ close
+
+
+
+ Medium
+
+
+ medium
+
+
+
+ Far
+
+
+ far
+
+
+
+ Opens a new menu to select from 'Close', 'Medium', or 'Far'.
+
+
+ 'There's infantry [tag]' → 'There's infantry close'
+
+
+
+ Call Check
+
+
+ [vl-ACECheck]ACE check
+
+
+
+ Green
+
+
+ green
+
+
+
+ Yellow
+
+
+ yellow
+
+
+
+ Red
+
+
+ red
+
+
+
+ Black
+
+
+ black
+
+
+
+
+ Opens a new menu to select from 'Permission to fire', 'Clear backblast', 'Backblast clear', or 'Rocket rocket rocket'.
+
+
+ '[tag]?' → 'Permission to fire?'
+
+
+
+ Permission to Fire?
+
+
+ [vl-AskFirePermission]Permission to fire
+
+
+
+ Clear Backblast
+
+
+ [vl-ClearBackblast]Clear backblast
+
+
+
+ Backblast Clear
+
+
+ [vl-BackblastClear]Backblast clear
+
+
+
+ Rocket Rocket Rocket!
+
+
+ [vl-RocketFire]Rocket rocket rocket
+
+
+
\ No newline at end of file
diff --git a/addons/chatwheel/ui/BaseControls.hpp b/addons/chatwheel/ui/BaseControls.hpp
new file mode 100644
index 0000000..5f4f212
--- /dev/null
+++ b/addons/chatwheel/ui/BaseControls.hpp
@@ -0,0 +1,36 @@
+class RscObject;
+class RscText;
+class RscFrame;
+class RscLine;
+class RscProgress;
+class RscPicture;
+class RscPictureKeepAspect;
+class RscVideo;
+class RscHTML;
+class RscButton;
+class RscShortcutButton;
+class RscEdit;
+class RscCombo;
+class RscListBox;
+class RscListNBox;
+class RscXListBox;
+class RscTree;
+class RscSlider;
+class RscXSliderH;
+class RscActiveText;
+class RscActivePicture;
+class RscActivePictureKeepAspect;
+class RscStructuredText;
+class RscToolbox;
+class RscControlsGroup;
+class RscControlsGroupNoScrollbars;
+class RscControlsGroupNoHScrollbars;
+class RscControlsGroupNoVScrollbars;
+class RscButtonTextOnly;
+class RscButtonMenu;
+class RscButtonMenuOK;
+class RscButtonMenuCancel;
+class RscButtonMenuSteam;
+class RscMapControl;
+class RscMapControlEmpty;
+class RscCheckBox;
\ No newline at end of file
diff --git a/addons/chatwheel/ui/RscChatWheel.hpp b/addons/chatwheel/ui/RscChatWheel.hpp
new file mode 100644
index 0000000..05e889e
--- /dev/null
+++ b/addons/chatwheel/ui/RscChatWheel.hpp
@@ -0,0 +1,19 @@
+class CWR_RscChatWheel {
+ idd = IDD_CHATWHEEL_MAIN;
+ duration = 1e+6;
+ onLoad = QUOTE(uiNamespace setVariable [ARR_2('CWR_RscChatWheel',_this select 0)];);
+ onUnload = QUOTE(uiNamespace setVariable [ARR_2('CWR_RscChatWheel',nil)]);
+
+ class Controls {
+ class Messages: RscListBox {
+ idc = IDC_CHATWHEEL_MESSAGES;
+ x = QUOTE(profileNamespace getVariable [ARR_2(QQUOTE(DOUBLES(IGUI,GVAR(grid_chatwheel_x))),GUI_GRID_CENTER_X)]);
+ y = QUOTE(profileNamespace getVariable [ARR_2(QQUOTE(DOUBLES(IGUI,GVAR(grid_chatwheel_y))),GUI_GRID_CENTER_Y)]);
+ w = QUOTE(profileNamespace getVariable [ARR_2(QQUOTE(DOUBLES(IGUI,GVAR(grid_chatwheel_w))),5 * GUI_GRID_CENTER_W)]);
+ h = QUOTE(profileNamespace getVariable [ARR_2(QQUOTE(DOUBLES(IGUI,GVAR(grid_chatwheel_h))),10 * GUI_GRID_CENTER_H)]);
+
+ colorText[] = IGUI_TEXT_COLOR;
+ colorBackground[] = IGUI_BCG_COLOR;
+ };
+ };
+};
\ No newline at end of file
diff --git a/addons/common/$PBOPREFIX$ b/addons/common/$PBOPREFIX$
new file mode 100644
index 0000000..790c7e6
--- /dev/null
+++ b/addons/common/$PBOPREFIX$
@@ -0,0 +1 @@
+z\cwr\addons\common
\ No newline at end of file
diff --git a/addons/common/CfgEventHandlers.hpp b/addons/common/CfgEventHandlers.hpp
new file mode 100644
index 0000000..6446b64
--- /dev/null
+++ b/addons/common/CfgEventHandlers.hpp
@@ -0,0 +1,11 @@
+class Extended_PreStart_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
+ };
+};
+
+class Extended_PreInit_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
+ };
+};
\ No newline at end of file
diff --git a/addons/Core/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp
similarity index 67%
rename from addons/Core/XEH_PREP.hpp
rename to addons/common/XEH_PREP.hpp
index 5b6d5fd..27c1ded 100644
--- a/addons/Core/XEH_PREP.hpp
+++ b/addons/common/XEH_PREP.hpp
@@ -1,6 +1,6 @@
PREP(isPlayer);
-PREP(removeQuotes);
PREP(stringReplace);
PREP(bearingToDirection);
PREP(getNearbyPlayers);
-PREP(sortByDistance);
\ No newline at end of file
+PREP(sortByDistance);
+PREP(truncate);
\ No newline at end of file
diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf
new file mode 100644
index 0000000..e08c5b8
--- /dev/null
+++ b/addons/common/XEH_preInit.sqf
@@ -0,0 +1,5 @@
+#include "script_component.hpp"
+
+PREP_RECOMPILE_START;
+#include "XEH_PREP.hpp"
+PREP_RECOMPILE_END;
\ No newline at end of file
diff --git a/addons/ChatWheel/XEH_preStart.sqf b/addons/common/XEH_preStart.sqf
similarity index 100%
rename from addons/ChatWheel/XEH_preStart.sqf
rename to addons/common/XEH_preStart.sqf
diff --git a/addons/common/config.cpp b/addons/common/config.cpp
new file mode 100644
index 0000000..e6e738d
--- /dev/null
+++ b/addons/common/config.cpp
@@ -0,0 +1,18 @@
+#include "script_component.hpp"
+
+class CfgPatches {
+ class ADDON {
+ author = AUTHOR;
+ authors[] = {"DartRuffian"};
+ name = COMPONENT_NAME;
+ requiredVersion = REQUIRED_VERSION;
+ requiredAddons[] = {
+ "cwr_main"
+ };
+ units[] = {};
+ weapons[] = {};
+ VERSION_CONFIG;
+ };
+};
+
+#include "CfgEventHandlers.hpp"
\ No newline at end of file
diff --git a/addons/common/functions/fnc_bearingToDirection.sqf b/addons/common/functions/fnc_bearingToDirection.sqf
new file mode 100644
index 0000000..82a6145
--- /dev/null
+++ b/addons/common/functions/fnc_bearingToDirection.sqf
@@ -0,0 +1,33 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Converts a bearing, a number from 0 to 360 inclusive, to a localized direction name.
+ *
+ * Arguments:
+ * 0: Bearing
+ *
+ * Return Value:
+ * The direction for the bearing
+ *
+ * Example:
+ * 90 call cwr_common_fnc_getDirFromBearing; // Returns "East"
+ *
+ * Public: Yes
+ */
+
+params [["_bearing", 0, [0]]];
+TRACE_1("fnc_bearingToDirection",_bearing);
+
+_bearing = CLAMP(_bearing,0,360);
+private _direction = switch (true) do {
+ case ((_bearing <= 22.5) or (_bearing >= 337.5)): {localize "STR_q_North"};
+ case (_bearing <= 67.5): {localize "STR_q_North_East"};
+ case (_bearing <= 112.5): {localize "STR_q_East"};
+ case (_bearing <= 157.5): {localize "STR_q_South_East"};
+ case (_bearing <= 202.5): {localize "STR_q_South"};
+ case (_bearing <= 247.5): {localize "STR_q_South_West"};
+ case (_bearing <= 292.5): {localize "STR_q_West"};
+ default {localize "STR_q_North_West"};
+};
+
+_direction;
\ No newline at end of file
diff --git a/addons/common/functions/fnc_getNearbyPlayers.sqf b/addons/common/functions/fnc_getNearbyPlayers.sqf
new file mode 100644
index 0000000..5177623
--- /dev/null
+++ b/addons/common/functions/fnc_getNearbyPlayers.sqf
@@ -0,0 +1,32 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Returns an array of players near a given position.
+ *
+ * Arguments:
+ * 0: Position in format PositionAGL
+ * 1: Radius in meters
+ *
+ * Return Value:
+ * Array of player units
+ *
+ * Example:
+ * [getPosAGL player, 30] call cwr_common_fnc_getNearbyPlayers;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_positionAGL", [0,0,0], [[]], 3],
+ ["_radius", 0, [0]]
+];
+TRACE_2("fnc_getNearbyPlayers",_positionAGL,_radius);
+
+if !(_positionAGL isEqualTypeParams [0,0,0]) exitWith {
+ WARNING_2("Array of non-numbers passed to %1. (%2)",_fnc_scriptName,_positionAGL);
+};
+
+private _nearbyUnits = _positionAGL nearEntities ["CAManBase", _radius];
+_nearbyUnits = _nearbyUnits select {_x call FUNC(isPlayer);};
+
+_nearbyUnits;
\ No newline at end of file
diff --git a/addons/Core/functions/fnc_isPlayer.sqf b/addons/common/functions/fnc_isPlayer.sqf
similarity index 53%
rename from addons/Core/functions/fnc_isPlayer.sqf
rename to addons/common/functions/fnc_isPlayer.sqf
index 65c4e1e..07bc8ea 100644
--- a/addons/Core/functions/fnc_isPlayer.sqf
+++ b/addons/common/functions/fnc_isPlayer.sqf
@@ -1,6 +1,6 @@
#include "..\script_component.hpp"
/*
- * Authors: DartRuffian
+ * Author: DartRuffian
* Checks if a given unit is a player, includes remote controlled units by default.
*
* Arguments:
@@ -8,21 +8,24 @@
* 1: Include remote controlled units (optional, default: true)
*
* Return Value:
- * Whether the unit is player controlled
+ * True if unit is player or remote controlled if set, false otherwise
*
* Example:
- * player call CWR_Core_fnc_isPlayer;
+ * player call cwr_common_fnc_isPlayer;
+ *
+ * Public: Yes
*/
-
-params [["_unit", objNull, [objNull]], ["_includeRemoteControlled", true, [true]]];
+params [
+ ["_unit", objNull, [objNull]],
+ ["_includeRemoteControlled", true, [true]]
+];
+TRACE_2("fnc_isPlayer",_unit,_includeRemoteControlled);
if (isNull _unit) exitWith {false};
-isPlayer _unit or
-{
- _includeRemoteControlled &&
- {
+isPlayer _unit or {
+ _includeRemoteControlled && {
!isNull (_unit getVariable ["bis_fnc_moduleRemoteControl_owner", objNull])
}
};
\ No newline at end of file
diff --git a/addons/common/functions/fnc_sortByDistance.sqf b/addons/common/functions/fnc_sortByDistance.sqf
new file mode 100644
index 0000000..01c4e35
--- /dev/null
+++ b/addons/common/functions/fnc_sortByDistance.sqf
@@ -0,0 +1,35 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Sorts an array of objects based on distance from a given position.
+ *
+ * Arguments:
+ * 0: Position in format PositionAGL.
+ * 1: Objects to sort.
+ * 2: Sorting order, true for ascending, false for descending.
+ *
+ * Return Value:
+ * The sorted objects
+ *
+ * Example:
+ * [ASLtoAGL getPosASL player, [unit1]] call cwr_common_fnc_sortByDistance;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_positionAGL", [0,0,0], [[]], 3],
+ ["_objects", [objNull], []],
+ ["_order", true, [true]]
+];
+if !(_positionAGL isEqualTypeParams [0,0,0] or {_objects isEqualTypeParams [objNull]}) exitWith {
+ WARNING_3("Bad parameters passed to %1. (%2, %3)",_fnc_scriptName,_positionAGL,_objects);
+};
+TRACE_3("fnc_sortByDistance",_positionAGL,_objects,_order);
+
+private _sorted = _objects apply {
+ [_positionAGL distance _x, _x];
+};
+_sorted sort _order;
+_objects = _sorted apply {_x#1};
+_objects;
\ No newline at end of file
diff --git a/addons/common/functions/fnc_stringReplace.sqf b/addons/common/functions/fnc_stringReplace.sqf
new file mode 100644
index 0000000..e8ce76d
--- /dev/null
+++ b/addons/common/functions/fnc_stringReplace.sqf
@@ -0,0 +1,52 @@
+#include "..\script_component.hpp"
+/*
+ * Author: Colin J.D. Stewart (PixeL_GaMMa)
+ * Edited By DartRuffian
+ * Replaces all occurences of substrings in a given string with a given value.
+ *
+ * Arguments:
+ * 0: The string to edit.
+ * 1: The substring(s).
+ * 2: The string to replace the substring(s) with.
+ *
+ * Return Value:
+ * The edited string
+ *
+ * Example:
+ * ["xxx is awesome, I love xxx!", "xxx", "Arma"] call cwr_common_fnc_stringReplace;
+ * ["xxx is awesome, I love yyy!", ["xxx", "yyy"], "Arma"] call cwr_common_fnc_stringReplace;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_str", "", [""]],
+ ["_find", [""], []],
+ ["_replace", "", []]
+];
+TRACE_3("fnc_stringReplace",_str,_find,_replace);
+
+if (_str isEqualTo "") exitWith {WARNING_1("Empty string passed to %1",_fnc_scriptName);};
+
+if !(_find isEqualType []) then {
+ _find = [_find];
+};
+if !(_replace isEqualType "") then {
+ _replace = str _replace;
+};
+
+{
+ private _return = "";
+ private _len = count _x;
+ private _pos = _str find _x;
+
+ while {(_pos != -1) && (count _str > 0)} do {
+ _return = _return + (_str select [0, _pos]) + _replace;
+
+ _str = (_str select [_pos + _len]);
+ _pos = _str find _x;
+ };
+ _str = _return + _str;
+} forEach _find;
+
+_str;
\ No newline at end of file
diff --git a/addons/common/functions/fnc_truncate.sqf b/addons/common/functions/fnc_truncate.sqf
new file mode 100644
index 0000000..ed6d98e
--- /dev/null
+++ b/addons/common/functions/fnc_truncate.sqf
@@ -0,0 +1,36 @@
+#include "..\script_component.hpp"
+/*
+ * Author: DartRuffian
+ * Truncates a string to a given length. The string will be trimmed before being truncated.
+ *
+ * Arguments:
+ * 0: The string
+ * 1: Maximum length (optional, default: 15)
+ * - Maximum length includes the given ending.
+ * 2: Ending (optional, default: " ...")
+ *
+ * Return Value:
+ * The edited string
+ *
+ * Example:
+ * ["This is a very long string", 15] call cwr_common_fnc_truncate;
+ *
+ * Public: Yes
+ */
+
+params [
+ ["_message", "", [""]],
+ ["_maxLength", 15, [0]],
+ ["_ending", " ...", [""]]
+];
+TRACE_3("fnc_truncate",_message,_maxLength,_ending);
+
+_message = _message call CBA_fnc_trim;
+private _length = count _message;
+
+if (_length <= _maxLength) exitWith { _message };
+
+_message = _message select [0, _maxLength - count _ending];
+_message = _message + _ending;
+
+_message;
\ No newline at end of file
diff --git a/addons/common/script_component.hpp b/addons/common/script_component.hpp
new file mode 100644
index 0000000..9b68d59
--- /dev/null
+++ b/addons/common/script_component.hpp
@@ -0,0 +1,9 @@
+#define COMPONENT common
+#define COMPONENT_BEAUTIFIED Common
+#include "\z\cwr\addons\main\script_mod.hpp"
+
+// #define DEBUG_MODE_FULL
+// #define DISABLE_COMPILE_CACHE
+// #define ENABLE_PERFORMANCE_COUNTERS
+
+#include "\z\cwr\addons\main\script_macros.hpp"
diff --git a/addons/compat_ace/$PBOPREFIX$ b/addons/compat_ace/$PBOPREFIX$
new file mode 100644
index 0000000..e459f67
--- /dev/null
+++ b/addons/compat_ace/$PBOPREFIX$
@@ -0,0 +1 @@
+z\cwr\addons\compat_ace
\ No newline at end of file
diff --git a/addons/compat_ace/CfgEventHandlers.hpp b/addons/compat_ace/CfgEventHandlers.hpp
new file mode 100644
index 0000000..6446b64
--- /dev/null
+++ b/addons/compat_ace/CfgEventHandlers.hpp
@@ -0,0 +1,11 @@
+class Extended_PreStart_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
+ };
+};
+
+class Extended_PreInit_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
+ };
+};
\ No newline at end of file
diff --git a/addons/compat_ace/XEH_PREP.hpp b/addons/compat_ace/XEH_PREP.hpp
new file mode 100644
index 0000000..34b560b
--- /dev/null
+++ b/addons/compat_ace/XEH_PREP.hpp
@@ -0,0 +1 @@
+// PREP(empty);
\ No newline at end of file
diff --git a/addons/compat_ace/XEH_preInit.sqf b/addons/compat_ace/XEH_preInit.sqf
new file mode 100644
index 0000000..e08c5b8
--- /dev/null
+++ b/addons/compat_ace/XEH_preInit.sqf
@@ -0,0 +1,5 @@
+#include "script_component.hpp"
+
+PREP_RECOMPILE_START;
+#include "XEH_PREP.hpp"
+PREP_RECOMPILE_END;
\ No newline at end of file
diff --git a/addons/Core/XEH_preStart.sqf b/addons/compat_ace/XEH_preStart.sqf
similarity index 100%
rename from addons/Core/XEH_preStart.sqf
rename to addons/compat_ace/XEH_preStart.sqf
diff --git a/addons/compat_ace/config.cpp b/addons/compat_ace/config.cpp
new file mode 100644
index 0000000..2c5b62a
--- /dev/null
+++ b/addons/compat_ace/config.cpp
@@ -0,0 +1,21 @@
+#include "script_component.hpp"
+
+class CfgPatches {
+ class ADDON {
+ author = AUTHOR;
+ authors[] = {"DartRuffian"};
+ name = COMPONENT_NAME;
+ requiredVersion = REQUIRED_VERSION;
+ requiredAddons[] = {
+ "cwr_loadorder",
+ "ace_main"
+ };
+ units[] = {};
+ weapons[] = {};
+ VERSION_CONFIG;
+
+ skipWhenMissingDependencies = 1;
+ };
+};
+
+#include "CfgEventHandlers.hpp"
\ No newline at end of file
diff --git a/addons/compat_ace/functions/fnc_empty.sqf b/addons/compat_ace/functions/fnc_empty.sqf
new file mode 100644
index 0000000..88db603
--- /dev/null
+++ b/addons/compat_ace/functions/fnc_empty.sqf
@@ -0,0 +1,16 @@
+#include "..\script_component.hpp"
+/*
+ * Author: You!
+ * An empty function that does nothing.
+ *
+ * Arguments:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call cwr_addonName_fnc_empty;
+ *
+ * Public: No
+ */
\ No newline at end of file
diff --git a/addons/compat_ace/grenades/CfgMagazines.hpp b/addons/compat_ace/grenades/CfgMagazines.hpp
new file mode 100644
index 0000000..adccddd
--- /dev/null
+++ b/addons/compat_ace/grenades/CfgMagazines.hpp
@@ -0,0 +1,20 @@
+class CfgMagazines {
+ class HandGrenade;
+ class ACE_HandFlare_Base: HandGrenade {
+ GVARMAIN(grenadeType) = ECSTRING(chatwheel,grenadeType_Flare);
+ };
+
+ class ACE_M84: HandGrenade {
+ GVARMAIN(grenadeType) = ECSTRING(chatwheel,grenadeType_Flashbang);
+ };
+
+ class ACE_CTS9: HandGrenade {
+ GVARMAIN(grenadeType) = ECSTRING(chatwheel,grenadeType_Flashbang);
+ };
+
+ class SmokeShell;
+ class ACE_M14: SmokeShell {
+ GVARMAIN(grenadeType) = ECSTRING(chatwheel,grenadeType_Incendiary);
+ GVARMAIN(grenadeLocalized) = ECSTRING(chatwheel,grenadeType_Incendiary_localized);
+ };
+};
\ No newline at end of file
diff --git a/addons/compat_ace/grenades/config.cpp b/addons/compat_ace/grenades/config.cpp
new file mode 100644
index 0000000..be2669f
--- /dev/null
+++ b/addons/compat_ace/grenades/config.cpp
@@ -0,0 +1,22 @@
+#include "script_component.hpp"
+
+class CfgPatches {
+ class SUBADDON {
+ author = AUTHOR;
+ authors[] = {"DartRuffian"};
+ name = COMPONENT_NAME;
+ addonRootClass = "ace_grenades";
+ requiredVersion = REQUIRED_VERSION;
+ requiredAddons[] = {
+ QUOTE(ADDON),
+ "ace_grenades"
+ };
+ units[] = {};
+ weapons[] = {};
+ VERSION_CONFIG;
+
+ skipWhenMissingDependencies = 1;
+ };
+};
+
+#include "CfgMagazines.hpp"
\ No newline at end of file
diff --git a/addons/compat_ace/grenades/script_component.hpp b/addons/compat_ace/grenades/script_component.hpp
new file mode 100644
index 0000000..e19a333
--- /dev/null
+++ b/addons/compat_ace/grenades/script_component.hpp
@@ -0,0 +1,4 @@
+#define SUBCOMPONENT grenades
+#define SUBCOMPONENT_BEAUTIFIED Grenades
+
+#include "..\script_component.hpp"
\ No newline at end of file
diff --git a/addons/compat_ace/script_component.hpp b/addons/compat_ace/script_component.hpp
new file mode 100644
index 0000000..6688e7a
--- /dev/null
+++ b/addons/compat_ace/script_component.hpp
@@ -0,0 +1,9 @@
+#define COMPONENT compat_ace
+#define COMPONENT_BEAUTIFIED ACE Compatibility
+#include "\z\cwr\addons\main\script_mod.hpp"
+
+// #define DEBUG_MODE_FULL
+// #define DISABLE_COMPILE_CACHE
+// #define ENABLE_PERFORMANCE_COUNTERS
+
+#include "\z\cwr\addons\main\script_macros.hpp"
diff --git a/addons/loadorder/$PBOPREFIX$ b/addons/loadorder/$PBOPREFIX$
new file mode 100644
index 0000000..90eea63
--- /dev/null
+++ b/addons/loadorder/$PBOPREFIX$
@@ -0,0 +1 @@
+z\cwr\addons\loadorder
\ No newline at end of file
diff --git a/addons/loadorder/config.cpp b/addons/loadorder/config.cpp
new file mode 100644
index 0000000..2adbf4a
--- /dev/null
+++ b/addons/loadorder/config.cpp
@@ -0,0 +1,18 @@
+#include "script_component.hpp"
+
+class CfgPatches {
+ class ADDON {
+ author = AUTHOR;
+ authors[] = {"DartRuffian"};
+ name = COMPONENT_NAME;
+ requiredVersion = REQUIRED_VERSION;
+ requiredAddons[] = {
+ "cwr_chatwheel",
+ "cwr_common",
+ "cwr_main"
+ };
+ units[] = {};
+ weapons[] = {};
+ VERSION_CONFIG;
+ };
+};
\ No newline at end of file
diff --git a/addons/loadorder/script_component.hpp b/addons/loadorder/script_component.hpp
new file mode 100644
index 0000000..4039764
--- /dev/null
+++ b/addons/loadorder/script_component.hpp
@@ -0,0 +1,9 @@
+#define COMPONENT loadorder
+#define COMPONENT_BEAUTIFIED Load Order
+#include "\z\cwr\addons\main\script_mod.hpp"
+
+// #define DEBUG_MODE_FULL
+// #define DISABLE_COMPILE_CACHE
+// #define ENABLE_PERFORMANCE_COUNTERS
+
+#include "\z\cwr\addons\main\script_macros.hpp"
diff --git a/addons/main/$PBOPREFIX$ b/addons/main/$PBOPREFIX$
new file mode 100644
index 0000000..9fb84c2
--- /dev/null
+++ b/addons/main/$PBOPREFIX$
@@ -0,0 +1 @@
+z\cwr\addons\main
\ No newline at end of file
diff --git a/addons/main/CfgEventHandlers.hpp b/addons/main/CfgEventHandlers.hpp
new file mode 100644
index 0000000..6446b64
--- /dev/null
+++ b/addons/main/CfgEventHandlers.hpp
@@ -0,0 +1,11 @@
+class Extended_PreStart_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
+ };
+};
+
+class Extended_PreInit_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
+ };
+};
\ No newline at end of file
diff --git a/addons/main/CfgSettings.hpp b/addons/main/CfgSettings.hpp
new file mode 100644
index 0000000..ab0ee77
--- /dev/null
+++ b/addons/main/CfgSettings.hpp
@@ -0,0 +1,11 @@
+class CfgSettings {
+ class CBA {
+ class Versioning {
+ class PREFIX {
+ class dependencies {
+ CBA[] = {"cba_main", REQUIRED_CBA_VERSION, QUOTE(true)};
+ };
+ };
+ };
+ };
+};
\ No newline at end of file
diff --git a/addons/main/XEH_PREP.hpp b/addons/main/XEH_PREP.hpp
new file mode 100644
index 0000000..51cb930
--- /dev/null
+++ b/addons/main/XEH_PREP.hpp
@@ -0,0 +1 @@
+// PREP(empty)
\ No newline at end of file
diff --git a/addons/main/XEH_preInit.sqf b/addons/main/XEH_preInit.sqf
new file mode 100644
index 0000000..e08c5b8
--- /dev/null
+++ b/addons/main/XEH_preInit.sqf
@@ -0,0 +1,5 @@
+#include "script_component.hpp"
+
+PREP_RECOMPILE_START;
+#include "XEH_PREP.hpp"
+PREP_RECOMPILE_END;
\ No newline at end of file
diff --git a/addons/Core/XEH_preInit.sqf b/addons/main/XEH_preStart.sqf
similarity index 100%
rename from addons/Core/XEH_preInit.sqf
rename to addons/main/XEH_preStart.sqf
diff --git a/addons/ChatWheel/config.cpp b/addons/main/config.cpp
similarity index 55%
rename from addons/ChatWheel/config.cpp
rename to addons/main/config.cpp
index ecd5e90..144ace6 100644
--- a/addons/ChatWheel/config.cpp
+++ b/addons/main/config.cpp
@@ -1,21 +1,19 @@
#include "script_component.hpp"
-#include "CfgEventHandlers.hpp"
-#include "CWR_MessageList.hpp"
-
-class CfgPatches
-{
- class ADDON
- {
- author = "DartRuffian";
+class CfgPatches {
+ class ADDON {
+ author = AUTHOR;
+ authors[] = {"DartRuffian"};
name = COMPONENT_NAME;
requiredVersion = REQUIRED_VERSION;
- requiredAddons[] =
- {
- QCLASS(Core)
+ requiredAddons[] = {
+ "cba_main"
};
units[] = {};
weapons[] = {};
VERSION_CONFIG;
};
-};
\ No newline at end of file
+};
+
+#include "CfgEventHandlers.hpp"
+#include "CfgSettings.hpp"
\ No newline at end of file
diff --git a/addons/main/data/hpp/defineDIKCodes.inc b/addons/main/data/hpp/defineDIKCodes.inc
new file mode 100644
index 0000000..a865ba0
--- /dev/null
+++ b/addons/main/data/hpp/defineDIKCodes.inc
@@ -0,0 +1,33 @@
+#include "\a3\ui_f\hpp\defineDIKCodes.inc"
+
+#define DIK_MOUSELEFT 0xF0
+#define DIK_MOUSERIGHT 0xF1
+#define DIK_MOUSEMIDDLE 0xF2
+#define DIK_MOUSE4 0xF3
+#define DIK_MOUSE5 0xF4
+#define DIK_MOUSE6 0xF5
+#define DIK_MOUSE7 0xF6
+#define DIK_MOUSE8 0xF7
+#define DIK_MOUSEUP 0xF8
+#define DIK_MOUSEDOWN 0xF9
+
+#define DIK_USERCUSTOM1 0xFA
+#define DIK_USERCUSTOM2 0xFB
+#define DIK_USERCUSTOM3 0xFC
+#define DIK_USERCUSTOM4 0xFD
+#define DIK_USERCUSTOM5 0xFE
+#define DIK_USERCUSTOM6 0xFF
+#define DIK_USERCUSTOM7 0x100
+#define DIK_USERCUSTOM8 0x101
+#define DIK_USERCUSTOM9 0x102
+#define DIK_USERCUSTOM10 0x103
+#define DIK_USERCUSTOM11 0x104
+#define DIK_USERCUSTOM12 0x105
+#define DIK_USERCUSTOM13 0x106
+#define DIK_USERCUSTOM14 0x107
+#define DIK_USERCUSTOM15 0x108
+#define DIK_USERCUSTOM16 0x109
+#define DIK_USERCUSTOM17 0x10A
+#define DIK_USERCUSTOM18 0x10B
+#define DIK_USERCUSTOM19 0x10C
+#define DIK_USERCUSTOM20 0x10D
\ No newline at end of file
diff --git a/addons/main/defines.hpp b/addons/main/defines.hpp
new file mode 100644
index 0000000..e7ea074
--- /dev/null
+++ b/addons/main/defines.hpp
@@ -0,0 +1,5 @@
+#define IGUI_SAVEX 0
+#define IGUI_SAVEY 1
+#define IGUI_SAVEW 2
+#define IGUI_SAVEH 3
+#define IGUI_SAVEALL IGUI_SAVEX, IGUI_SAVEY, IGUI_SAVEW, IGUI_SAVEH
\ No newline at end of file
diff --git a/addons/main/functions/fnc_empty.sqf b/addons/main/functions/fnc_empty.sqf
new file mode 100644
index 0000000..5ddb4fe
--- /dev/null
+++ b/addons/main/functions/fnc_empty.sqf
@@ -0,0 +1,16 @@
+#include "..\script_component.hpp"
+/*
+ * Author: You!
+ * An empty function that does nothing.
+ *
+ * Arguments:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call cwr_common_fnc_empty;
+ *
+ * Public: No
+ */
\ No newline at end of file
diff --git a/addons/main/script_component.hpp b/addons/main/script_component.hpp
new file mode 100644
index 0000000..fce0607
--- /dev/null
+++ b/addons/main/script_component.hpp
@@ -0,0 +1,9 @@
+#define COMPONENT main
+#define COMPONENT_BEAUTIFIED Main
+#include "\z\cwr\addons\main\script_mod.hpp"
+
+// #define DEBUG_MODE_FULL
+// #define DISABLE_COMPILE_CACHE
+
+#include "\z\cwr\addons\main\script_macros.hpp"
+#include "defines.hpp"
\ No newline at end of file
diff --git a/addons/main/script_macros.hpp b/addons/main/script_macros.hpp
new file mode 100644
index 0000000..f03881f
--- /dev/null
+++ b/addons/main/script_macros.hpp
@@ -0,0 +1,53 @@
+// Global toggles for caching/logging
+// #define DISABLE_COMPILE_CACHE
+// #define DEBUG_MODE_FULL
+#define DEBUG_SYNCHRONOUS
+
+#include "\x\cba\addons\main\script_macros_common.hpp"
+
+#define QQUOTE(var1) QUOTE(QUOTE(var1))
+
+// Functions
+#define DFUNC(var1) TRIPLES(ADDON,fnc,var1)
+#define DEFUNC(var1,var2) TRIPLES(DOUBLES(PREFIX,var1),fnc,var2)
+
+#undef PREP
+#ifdef DISABLE_COMPILE_CACHE
+ #define LINKFUNC(x) {_this call FUNC(x)}
+ #define PREP(fncName) DFUNC(fncName) = compile preprocessFileLineNumbers QPATHTOF(functions\DOUBLES(fnc,fncName).sqf)
+ #define PREP_RECOMPILE_START if (isNil "ACE_PREP_recompile") then {ACE_recompiles = []; ACE_PREP_recompile = {{call _x} forEach ACE_recompiles;}}; private _recomp = {
+ #define PREP_RECOMPILE_END }; call _recomp; ACE_recompiles pushBack _recomp;
+#else
+ #define LINKFUNC(x) FUNC(x)
+ #define PREP(fncName) [QPATHTOF(functions\DOUBLES(fnc,fncName).sqf), QFUNC(fncName)] call CBA_fnc_compileFunction
+ #define PREP_RECOMPILE_START ; /* disabled */
+ #define PREP_RECOMPILE_END ; /* disabled */
+#endif
+
+#define QLLSTRING(var1) localize QQUOTE(TRIPLES(STR,ADDON,var1))
+
+#define ADDON_LOADED(var1) isClass (configFile >> "CfgPatches" >> QUOTE(var1))
+
+#define GETVAR_SYS(var1,var2) getVariable [ARR_2(QUOTE(var1),var2)]
+#define SETVAR_SYS(var1,var2) setVariable [ARR_2(QUOTE(var1),var2)]
+#define SETPVAR_SYS(var1,var2) setVariable [ARR_3(QUOTE(var1),var2,true)]
+
+#undef GETVAR
+#define GETVAR(var1,var2,var3) (var1 GETVAR_SYS(var2,var3))
+#define GETMVAR(var1,var2) (missionNamespace GETVAR_SYS(var1,var2))
+#define GETUVAR(var1,var2) (uiNamespace GETVAR_SYS(var1,var2))
+#define GETPRVAR(var1,var2) (profileNamespace GETVAR_SYS(var1,var2))
+#define GETPAVAR(var1,var2) (parsingNamespace GETVAR_SYS(var1,var2))
+
+#undef SETVAR
+#define SETVAR(var1,var2,var3) var1 SETVAR_SYS(var2,var3)
+#define SETPVAR(var1,var2,var3) var1 SETPVAR_SYS(var2,var3)
+#define SETMVAR(var1,var2) missionNamespace SETVAR_SYS(var1,var2)
+#define SETUVAR(var1,var2) uiNamespace SETVAR_SYS(var1,var2)
+#define SETPRVAR(var1,var2) profileNamespace SETVAR_SYS(var1,var2)
+#define SETPAVAR(var1,var2) parsingNamespace SETVAR_SYS(var1,var2)
+
+#define GETGVAR(var1,var2) GETMVAR(GVAR(var1),var2)
+#define GETEGVAR(var1,var2,var3) GETMVAR(EGVAR(var1,var2),var3)
+
+#define CLAMP(var1,lower,upper) lower max (var1 min upper)
\ No newline at end of file
diff --git a/addons/Core/script_mod.hpp b/addons/main/script_mod.hpp
similarity index 70%
rename from addons/Core/script_mod.hpp
rename to addons/main/script_mod.hpp
index 480816f..ce71fd1 100644
--- a/addons/Core/script_mod.hpp
+++ b/addons/main/script_mod.hpp
@@ -1,10 +1,13 @@
-#define MAINPREFIX DA
-#define PREFIX CWR
+#define MAINPREFIX z
+#define PREFIX cwr
#define MOD_NAME Chat Wheel Redux
+#define AUTHOR "DartRuffian"
-#include "\DA\CWR\addons\Core\script_version.hpp"
+#include "\z\cwr\addons\main\script_version.hpp"
-#define REQUIRED_VERSION 2.14
+#define REQUIRED_VERSION 2.18
+#define REQUIRED_CBA_VERSION {3,18,0}
+#define REQUIRED_ACE_VERSION {3,18,0}
#define VERSION MAJOR.MINOR
#define VERSION_STR MAJOR.MINOR.PATCH.BUILD
diff --git a/addons/Core/script_version.hpp b/addons/main/script_version.hpp
similarity index 50%
rename from addons/Core/script_version.hpp
rename to addons/main/script_version.hpp
index 83e519f..e890513 100644
--- a/addons/Core/script_version.hpp
+++ b/addons/main/script_version.hpp
@@ -1,4 +1,4 @@
#define MAJOR 1
-#define MINOR 0
+#define MINOR 4
#define PATCH 0
-#define BUILD 0
\ No newline at end of file
+#define BUILD 1
\ No newline at end of file
diff --git a/CWR.code-workspace b/cwr.code-workspace
similarity index 66%
rename from CWR.code-workspace
rename to cwr.code-workspace
index 5f8398d..a4a8e08 100644
--- a/CWR.code-workspace
+++ b/cwr.code-workspace
@@ -1,12 +1,10 @@
{
- "folders":
- [
+ "folders": [
{
"path": "./"
}
],
- "settings":
- {
+ "settings": {
"editor.insertSpaces": true,
"editor.detectIndentation": false,
@@ -15,9 +13,12 @@
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": false,
- "files.associations":
- {
- "*.hpp": "cpp"
+ "files.associations": {
+ "*.cpp": "cpp",
+ "*.hpp": "cpp",
+ "*.inc": "cpp",
+ "*.cfg": "cpp",
+ "*.rvmat": "cpp"
},
"C_Cpp.errorSquiggles": "disabled",
diff --git a/docs/README.md b/docs/README.md
index 0991ab5..a271b4d 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,31 +1,46 @@
-
-
-
-
-[](https://github.com/DartRuffian/A3-ChatWheel-Redux/graphs/contributors)
-[](https://steamcommunity.com/sharedfiles/filedetails/?id=3005504621)
-
-
-
----
-
-> "Thank you Dart for making my 'minimum fit for purpose' mod I made for, like, three of my unit members into something legit super accessible to the broader community."
-> - _Jenna_, the original creator of the script this mod is based on. [Source (Legion Studios Discord)](https://ptb.discord.com/channels/461042140756180992/1130867599345987604/1130901200498343938)
+
+
+Chat Wheel Redux
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Requires the latest version of CBA A3
+
**Chat Wheel Redux** (_CWR_) is a mostly client-side communication mod, allowing players without the ability to speak to communicate with other players easier. It is primarily intended for mute players who cannot communicate via microphone, but can also assist deaf or hard-of-hearing players if other players also use the mod to help communicate with them.
+The project is entirely **open-source** and any contributions to fix other mods are welcome.
+
Chat Wheel Redux is mostly feature complete; however, some of the planned features are: messages when taking damage; when a player is knocked unconcious (ACE); or killed. These will be able to be toggled on or off, similar to the automated messages for throwing grenades functions. They may each recieve their own settings in the future for more customization options.
+## Contributing
+For new contributers, see the [Contributing Setup & Guidelines](./.github/CONTRIBUTING.md).
+
## Issues
-Experiencing an issue? Check out the [Common Issues post](https://github.com/DartRuffian/A3-ChatWheel-Redux/issues/1) to see if your issue is listed.
-If your issue is not listed, please create one with the appropiate [label](https://github.com/DartRuffian/A3-ChatWheel-Redux/labels).
+Experiencing an issue? Check out the [Common Issues post](https://github.com/DartsArmaMods/A3-ChatWheel-Redux/issues/1) to see if your issue is listed.
+If your issue is not listed, please create [a new issue](https://github.com/DartsArmaMods/ChatWheelRedux/issues/new)
-## Usage & Modification
-This mod can be freely used by any player or any server.
+## Usage and modification
+This mod can be freely used by any player or any non-monetized server.
You are free to modify the mod for you or your group's own purposes if you:
- Notify me on Discord (dartruffian).
- Acknowledge that a fork Chat Wheel Redux is included in your mod(s).
+
+---
+
+> "Thank you Dart for making my 'minimum fit for purpose' mod I made for, like, three of my unit members into something legit super accessible to the broader community."
+> - _Jenna_, the original creator of the script this mod is based on. [Source (Legion Studios Discord)](https://ptb.discord.com/channels/461042140756180992/1130867599345987604/1130901200498343938)
\ No newline at end of file
diff --git a/extra/example_addon/$PBOPREFIX$ b/extra/example_addon/$PBOPREFIX$
new file mode 100644
index 0000000..4cb5249
--- /dev/null
+++ b/extra/example_addon/$PBOPREFIX$
@@ -0,0 +1 @@
+z\cwr\addons\addonName
\ No newline at end of file
diff --git a/extra/example_addon/CfgEventHandlers.hpp b/extra/example_addon/CfgEventHandlers.hpp
new file mode 100644
index 0000000..6446b64
--- /dev/null
+++ b/extra/example_addon/CfgEventHandlers.hpp
@@ -0,0 +1,11 @@
+class Extended_PreStart_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
+ };
+};
+
+class Extended_PreInit_EventHandlers {
+ class ADDON {
+ init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
+ };
+};
\ No newline at end of file
diff --git a/extra/example_addon/XEH_PREP.hpp b/extra/example_addon/XEH_PREP.hpp
new file mode 100644
index 0000000..34b560b
--- /dev/null
+++ b/extra/example_addon/XEH_PREP.hpp
@@ -0,0 +1 @@
+// PREP(empty);
\ No newline at end of file
diff --git a/extra/example_addon/XEH_preInit.sqf b/extra/example_addon/XEH_preInit.sqf
new file mode 100644
index 0000000..e08c5b8
--- /dev/null
+++ b/extra/example_addon/XEH_preInit.sqf
@@ -0,0 +1,5 @@
+#include "script_component.hpp"
+
+PREP_RECOMPILE_START;
+#include "XEH_PREP.hpp"
+PREP_RECOMPILE_END;
\ No newline at end of file
diff --git a/extra/example_addon/XEH_preStart.sqf b/extra/example_addon/XEH_preStart.sqf
new file mode 100644
index 0000000..3880138
--- /dev/null
+++ b/extra/example_addon/XEH_preStart.sqf
@@ -0,0 +1,3 @@
+#include "script_component.hpp"
+
+#include "XEH_PREP.hpp"
\ No newline at end of file
diff --git a/addons/Core/config.cpp b/extra/example_addon/config.cpp
similarity index 52%
rename from addons/Core/config.cpp
rename to extra/example_addon/config.cpp
index a0c3b68..19d8e7c 100644
--- a/addons/Core/config.cpp
+++ b/extra/example_addon/config.cpp
@@ -1,20 +1,18 @@
#include "script_component.hpp"
-
-class CfgPatches
-{
- class ADDON
- {
- author = "DartRuffian";
+class CfgPatches {
+ class ADDON {
+ author = AUTHOR;
+ authors[] = {"You!"};
name = COMPONENT_NAME;
requiredVersion = REQUIRED_VERSION;
- requiredAddons[] =
- {
- "A3_Data_F_Decade_Loadorder",
- "cba_main"
+ requiredAddons[] = {
+ "cwr_main"
};
units[] = {};
weapons[] = {};
VERSION_CONFIG;
};
-};
\ No newline at end of file
+};
+
+#include "CfgEventHandlers.hpp"
\ No newline at end of file
diff --git a/extra/example_addon/functions/fnc_empty.sqf b/extra/example_addon/functions/fnc_empty.sqf
new file mode 100644
index 0000000..88db603
--- /dev/null
+++ b/extra/example_addon/functions/fnc_empty.sqf
@@ -0,0 +1,16 @@
+#include "..\script_component.hpp"
+/*
+ * Author: You!
+ * An empty function that does nothing.
+ *
+ * Arguments:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [] call cwr_addonName_fnc_empty;
+ *
+ * Public: No
+ */
\ No newline at end of file
diff --git a/extra/example_addon/script_component.hpp b/extra/example_addon/script_component.hpp
new file mode 100644
index 0000000..529cc8d
--- /dev/null
+++ b/extra/example_addon/script_component.hpp
@@ -0,0 +1,9 @@
+#define COMPONENT addonName
+#define COMPONENT_BEAUTIFIED Addon Name
+#include "\z\cwr\addons\main\script_mod.hpp"
+
+// #define DEBUG_MODE_FULL
+// #define DISABLE_COMPILE_CACHE
+// #define ENABLE_PERFORMANCE_COUNTERS
+
+#include "\z\cwr\addons\main\script_macros.hpp"
diff --git a/extra/example_subaddon/config.cpp b/extra/example_subaddon/config.cpp
new file mode 100644
index 0000000..edb7628
--- /dev/null
+++ b/extra/example_subaddon/config.cpp
@@ -0,0 +1,17 @@
+#include "script_component.hpp"
+
+class CfgPatches {
+ class SUBADDON {
+ author = AUTHOR;
+ authors[] = {"You!"};
+ name = COMPONENT_NAME;
+ addonRootClass = QUOTE(ADDON);
+ requiredVersion = REQUIRED_VERSION;
+ requiredAddons[] = {
+ QUOTE(ADDON)
+ };
+ units[] = {};
+ weapons[] = {};
+ VERSION_CONFIG;
+ };
+};
\ No newline at end of file
diff --git a/extra/example_subaddon/script_component.hpp b/extra/example_subaddon/script_component.hpp
new file mode 100644
index 0000000..d4818d3
--- /dev/null
+++ b/extra/example_subaddon/script_component.hpp
@@ -0,0 +1,4 @@
+#define SUBCOMPONENT subaddonName
+#define SUBCOMPONENT_BEAUTIFIED Sub Addon
+
+#include "..\script_component.hpp"
\ No newline at end of file
diff --git a/hemtt.exe b/hemtt.exe
deleted file mode 100644
index 5cfb72c..0000000
Binary files a/hemtt.exe and /dev/null differ
diff --git a/include/a3/ui_f/hpp/defineCommonColors.inc b/include/a3/ui_f/hpp/defineCommonColors.inc
new file mode 100644
index 0000000..5370c07
--- /dev/null
+++ b/include/a3/ui_f/hpp/defineCommonColors.inc
@@ -0,0 +1,316 @@
+///////////////////////////////////////////////////////////////////////////
+/// GUI
+///////////////////////////////////////////////////////////////////////////
+
+//--- Background color with defaults (not multipliable)
+#define GUI_BCG_RGB_R "(profilenamespace getvariable ['GUI_BCG_RGB_R',0.13])"
+#define GUI_BCG_RGB_G "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.54])"
+#define GUI_BCG_RGB_B "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.21])"
+#define GUI_BCG_ALPHA "(profilenamespace getvariable ['GUI_BCG_RGB_A',0.8])"
+
+#define GUI_BCG_RGB GUI_BCG_RGB_R, GUI_BCG_RGB_G, GUI_BCG_RGB_B
+#define GUI_BCG_COLOR {GUI_BCG_RGB,GUI_BCG_ALPHA}
+#define GUI_BCG_COLOR_SELECTED {GUI_BCG_RGB,0.5}
+
+//--- TitleBar text color
+#define GUI_TITLETEXT_RGB_R "(profilenamespace getvariable ['GUI_TITLETEXT_RGB_R',1.0])"
+#define GUI_TITLETEXT_RGB_G "(profilenamespace getvariable ['GUI_TITLETEXT_RGB_G',1.0])"
+#define GUI_TITLETEXT_RGB_B "(profilenamespace getvariable ['GUI_TITLETEXT_RGB_B',1.0])"
+#define GUI_TITLETEXT_ALPHA "(profilenamespace getvariable ['GUI_TITLETEXT_RGB_A',0.6])"
+#define GUI_TITLETEXT_COLOR {GUI_TITLETEXT_RGB_R, GUI_TITLETEXT_RGB_G, GUI_TITLETEXT_RGB_B, GUI_TITLETEXT_ALPHA}
+
+//--- Background for wGUI displays
+#define GUI_BCG_MENU_RGB 0, 0, 0
+#define GUI_BCG_MENU {GUI_BCG_MENU_RGB, 0.7}
+
+//--- Background for editor
+#define GUI_BCG_EDITOR_RGB 0.1, 0.1, 0.1
+#define GUI_BCG_EDITOR {GUI_BCG_EDITOR_RGB, 1}
+
+//--- Medium background (obsolete; Dwarden's displays)
+#define GUI_BCG_MEDIUM_RGB GUI_BCG_RGB
+#define GUI_BCG_MEDIUM_ALPHA GUI_BCG_ALPHA
+#define GUI_BCG_MEDIUM_COLOR {GUI_BCG_MEDIUM_RGB,GUI_BCG_MEDIUM_ALPHA}
+
+//--- Dark background (HUD)
+#define GUI_BCG_DARK_RGB GUI_BCG_RGB
+#define GUI_BCG_DARK_ALPHA 0.85
+#define GUI_BCG_DARK_COLOR {GUI_BCG_DARK_RGB,GUI_BCG_DARK_ALPHA}
+#define GUI_BCG_DARK_TRANSPARENT {GUI_BCG_DARK_RGB,GUI_BCG_DARK_ALPHA / 2}
+
+//--- Active color (inversed to selected color)
+#define GUI_BCG_ACTIVE_RGB 1, 1, 1
+
+//--- Warning color (exit buttons)
+#define GUI_BCG_ERROR_RGB 0.7, 0, 0
+
+//--- Text color
+#define GUI_TEXT_RGB 1, 1, 1
+#define GUI_TEXT_ALPHA 1.0
+#define GUI_TEXT_COLOR {GUI_TEXT_RGB,GUI_TEXT_ALPHA}
+#define GUI_TEXT_SHADOW {0,0,0,0.5}
+#define GUI_TEXT_HTML_COLOR "#ffffff"
+#define GUI_TEXT_HTML_SHADOW "#80000000"
+
+//--- List: text colors and background highlight
+#define GUI_LIST_TEXT_COLOR {GUI_TEXT_RGB,0.8}
+#define GUI_LIST_TEXT_COLOR_SELECTED {GUI_TEXT_RGB,1.0}
+#define GUI_LIST_BCG_SELECTED {0,0,0,0.2}
+
+//--- Tooltip colours
+#define GUI_TOOLTIP_TEXT_COLOR {1, 1, 1, 1}
+#define GUI_TOOLTIP_BOX_COLOR {1, 1, 1, 1}
+#define GUI_TOOLTIP_SHADE_COLOR {0, 0, 0, 0.65}
+
+
+///////////////////////////////////////////////////////////////////////////
+/// iGUI
+///////////////////////////////////////////////////////////////////////////
+//--- IGUI Background color
+#define IGUI_BCG_RGB_R "(profilenamespace getvariable ['IGUI_BCG_RGB_R',0])"
+#define IGUI_BCG_RGB_G "(profilenamespace getvariable ['IGUI_BCG_RGB_G',1])"
+#define IGUI_BCG_RGB_B "(profilenamespace getvariable ['IGUI_BCG_RGB_B',1])"
+#define IGUI_BCG_RGB_A "(profilenamespace getvariable ['IGUI_BCG_RGB_A',0.8])"
+#define IGUI_BCG_RGB IGUI_BCG_RGB_R, IGUI_BCG_RGB_G, IGUI_BCG_RGB_B
+#define IGUI_BCG_COLOR {IGUI_BCG_RGB,IGUI_BCG_RGB_A}
+
+//--- IGUI Text color
+#define IGUI_TEXT_RGB_R "(profilenamespace getvariable ['IGUI_TEXT_RGB_R',0])"
+#define IGUI_TEXT_RGB_G "(profilenamespace getvariable ['IGUI_TEXT_RGB_G',1])"
+#define IGUI_TEXT_RGB_B "(profilenamespace getvariable ['IGUI_TEXT_RGB_B',1])"
+#define IGUI_TEXT_RGB_A "(profilenamespace getvariable ['IGUI_TEXT_RGB_A',0.8])"
+#define IGUI_TEXT_RGB IGUI_TEXT_RGB_R, IGUI_TEXT_RGB_G, IGUI_TEXT_RGB_B
+#define IGUI_TEXT_COLOR {IGUI_TEXT_RGB,IGUI_TEXT_RGB_A}
+
+//--- IGUI Warning color
+#define IGUI_WARNING_RGB_R "(profilenamespace getvariable ['IGUI_WARNING_RGB_R',0.8])"
+#define IGUI_WARNING_RGB_G "(profilenamespace getvariable ['IGUI_WARNING_RGB_G',0.5])"
+#define IGUI_WARNING_RGB_B "(profilenamespace getvariable ['IGUI_WARNING_RGB_B',0.0])"
+#define IGUI_WARNING_RGB_A "(profilenamespace getvariable ['IGUI_WARNING_RGB_A',0.8])"
+#define IGUI_WARNING_RGB IGUI_WARNING_RGB_R, IGUI_WARNING_RGB_G, IGUI_WARNING_RGB_B
+#define IGUI_WARNING_COLOR {IGUI_WARNING_RGB,IGUI_WARNING_RGB_A}
+
+//--- IGUI Error color
+#define IGUI_ERROR_RGB_R "(profilenamespace getvariable ['IGUI_ERROR_RGB_R',0.8])"
+#define IGUI_ERROR_RGB_G "(profilenamespace getvariable ['IGUI_ERROR_RGB_G',0.0])"
+#define IGUI_ERROR_RGB_B "(profilenamespace getvariable ['IGUI_ERROR_RGB_B',0.0])"
+#define IGUI_ERROR_RGB_A "(profilenamespace getvariable ['IGUI_ERROR_RGB_A',1.0])"
+#define IGUI_ERROR_RGB IGUI_ERROR_RGB_R, IGUI_ERROR_RGB_G, IGUI_ERROR_RGB_B
+#define IGUI_ERROR_COLOR {IGUI_ERROR_RGB,IGUI_ERROR_RGB_A}
+
+//--- IGUI Tactical ping color
+#define IGUI_TACTPING_RGB_R "(profilenamespace getvariable ['IGUI_TACTPING_RGB_R',1.0])"
+#define IGUI_TACTPING_RGB_G "(profilenamespace getvariable ['IGUI_TACTPING_RGB_G',0.8])"
+#define IGUI_TACTPING_RGB_B "(profilenamespace getvariable ['IGUI_TACTPING_RGB_B',0.2])"
+#define IGUI_TACTPING_RGB_A "(profilenamespace getvariable ['IGUI_TACTPING_RGB_A',1.0])"
+#define IGUI_TACTPING_RGB IGUI_TACTPING_RGB_R, IGUI_TACTPING_RGB_G, IGUI_TACTPING_RGB_B
+#define IGUI_TACTPING_COLOR {IGUI_TACTPING_RGB,IGUI_TACTPING_RGB_A}
+
+//--- HUD Text color (obsolete defines; ToDo: Replace with IGUI_TEXT_COLOR and IGUI_BCG_COLOR)
+#define CA_UI_HUD IGUI_TEXT_COLOR
+
+
+
+///////////////////////////////////////////////////////////////////////////
+/// Sides
+///////////////////////////////////////////////////////////////////////////
+
+//--- BLUFOR
+#define Map_BLUFOR_R "(profilenamespace getvariable ['Map_BLUFOR_R',0])"
+#define Map_BLUFOR_G "(profilenamespace getvariable ['Map_BLUFOR_G',1])"
+#define Map_BLUFOR_B "(profilenamespace getvariable ['Map_BLUFOR_B',1])"
+#define Map_BLUFOR_A "(profilenamespace getvariable ['Map_BLUFOR_A',0.8])"
+#define Map_BLUFOR_RGB Map_BLUFOR_R, Map_BLUFOR_G, Map_BLUFOR_B
+#define Map_BLUFOR_RGBA {Map_BLUFOR_RGB,Map_BLUFOR_A}
+
+//--- OPFOR
+#define Map_OPFOR_R "(profilenamespace getvariable ['Map_OPFOR_R',0])"
+#define Map_OPFOR_G "(profilenamespace getvariable ['Map_OPFOR_G',1])"
+#define Map_OPFOR_B "(profilenamespace getvariable ['Map_OPFOR_B',1])"
+#define Map_OPFOR_A "(profilenamespace getvariable ['Map_OPFOR_A',0.8])"
+#define Map_OPFOR_RGB Map_OPFOR_R, Map_OPFOR_G, Map_OPFOR_B
+#define Map_OPFOR_RGBA {Map_OPFOR_RGB,Map_OPFOR_A}
+
+//--- Independent
+#define Map_Independent_R "(profilenamespace getvariable ['Map_Independent_R',0])"
+#define Map_Independent_G "(profilenamespace getvariable ['Map_Independent_G',1])"
+#define Map_Independent_B "(profilenamespace getvariable ['Map_Independent_B',1])"
+#define Map_Independent_A "(profilenamespace getvariable ['Map_Independent_A',0.8])"
+#define Map_Independent_RGB Map_Independent_R, Map_Independent_G, Map_Independent_B
+#define Map_Independent_RGBA {Map_Independent_RGB,Map_Independent_A}
+
+//--- Civilian
+#define Map_Civilian_R "(profilenamespace getvariable ['Map_Civilian_R',0])"
+#define Map_Civilian_G "(profilenamespace getvariable ['Map_Civilian_G',1])"
+#define Map_Civilian_B "(profilenamespace getvariable ['Map_Civilian_B',1])"
+#define Map_Civilian_A "(profilenamespace getvariable ['Map_Civilian_A',0.8])"
+#define Map_Civilian_RGB Map_Civilian_R, Map_Civilian_G, Map_Civilian_B
+#define Map_Civilian_RGBA {Map_Civilian_RGB,Map_Civilian_A}
+
+//--- Unknown
+#define Map_Unknown_R "(profilenamespace getvariable ['Map_Unknown_R',0])"
+#define Map_Unknown_G "(profilenamespace getvariable ['Map_Unknown_G',1])"
+#define Map_Unknown_B "(profilenamespace getvariable ['Map_Unknown_B',1])"
+#define Map_Unknown_A "(profilenamespace getvariable ['Map_Unknown_A',0.8])"
+#define Map_Unknown_RGB Map_Unknown_R, Map_Unknown_G, Map_Unknown_B
+#define Map_Unknown_RGBA {Map_Unknown_RGB,Map_Unknown_A}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+/// Misc
+///////////////////////////////////////////////////////////////////////////
+//overwritten by Warka
+#define CA_UI_ACTION {0.9,0.9,0.9,0.4}
+#define CA_UI_ACTION_AVAILABLE IGUI_TEXT_COLOR
+#define CA_UI_ACTION_ACTIVE {0.24,0.87,0,0.8}
+#define CA_IGUI_Green {0.709,0.972,0.384,1}
+#define CA_IGUI_GreenDark {0.259,0.463,0.149, 1} //MUF-added from A3 //{0.659,0.863,0.549,0.6}
+#define CA_IGUI_Background IGUI_BCG_COLOR
+
+#define Color_Orange {GUI_BCG_RGB, 1}
+#define Color_DarkOrange {GUI_BCG_MEDIUM_RGB, 0.7}
+
+#define CA_colordark {0, 0, 0, 1}
+#define CA_UI_element_background Color_White
+#define CA_UI_background {0.6, 0.6, 0.6, 0.4}
+#define CA_UI_title_background {0.1961,0.1451,0.0941,1.0}
+#define CA_UI_green {0.709,0.972,0.384,1}
+#define CA_UI_red {0.58, 0.1147, 0.1108, 1}
+
+#define CA_UI_grey {0.4,0.4,0.4,1}
+#define CA_UI_transparent {1,1,1,0}
+
+#define CA_IGUI_Red {0.706,0.0745,0.0196,1}
+#define CA_IGUI_Orange {0.863,0.584,0.0,1}
+#define CA_IGUI_YellowGreen {0.8275,0.8196,0.1961,1.0}
+#define CA_IGUI_Blue {0.196,0.592,0.706, 1}
+#define CA_IGUI_Grey {0.606,0.606,0.606,1}
+
+#define Color_White {0.95, 0.95, 0.95, 1}
+//#define Color_Black {0.023529, 0, 0.0313725, 1}
+#define Color_Black {0, 0, 0, 1}
+#define Color_Gray {1, 1, 1, 0.5}
+#define Color_Empty {0, 0, 0, 0}
+
+#define Color_Back {0.1, 0.1, 0.1, 0.4}
+#define Color_BackList {0.2, 0.2, 0.2, 0.2}
+
+#define ProcTextWhite "#(argb,8,8,3)color(1,1,1,1)"
+#define ProcTextBlack "#(argb,8,8,3)color(0,0,0,1)"
+#define ProcTextGray "#(argb,8,8,3)color(0.3,0.3,0.3,1)"
+#define ProcTextRed "#(argb,8,8,3)color(1,0,0,1)"
+#define ProcTextGreen "#(argb,8,8,3)color(0,1,0,1)"
+#define ProcTextBlue "#(argb,8,8,3)color(0,0,1,1)"
+#define ProcTextOrange "#(argb,8,8,3)color(1,0.5,0,1)"
+#define ProcTextTransparent "#(argb,8,8,3)color(0,0,0,0)"
+#define ProcTextHUD "#(argb,8,8,3)color(0.600,0.8392,0.4706,1.0)"
+#define ProcTextPurple "#(argb,8,8,3)color(0.75,0,0.75,1)"
+
+
+///////////////////////////////////////////////////////////////////////////
+/// Task colors: 3D task marker
+///////////////////////////////////////////////////////////////////////////
+#define COLOR_TASK_ICON_UNASSIGNED_RGB 1,1,1
+#define COLOR_TASK_ICON_UNASSIGNED_A 0.5
+#define COLOR_TASK_ICON_UNASSIGNED_RGBA COLOR_TASK_ICON_UNASSIGNED_RGB,COLOR_TASK_ICON_UNASSIGNED_A
+#define COLOR_TASK_ICON_ASSIGNED_RGB 1,0.72,0.3
+#define COLOR_TASK_ICON_ASSIGNED_A 0.5
+#define COLOR_TASK_ICON_ASSIGNED_RGBA COLOR_TASK_ICON_ASSIGNED_RGB,COLOR_TASK_ICON_ASSIGNED_A
+#define COLOR_TASK_ICON_CUSTOM_RGB 0.3,0.72,1
+#define COLOR_TASK_ICON_CUSTOM_A 0.5
+#define COLOR_TASK_ICON_CUSTOM_RGBA COLOR_TASK_ICON_CUSTOM_RGB,COLOR_TASK_ICON_CUSTOM_A
+
+#define COLOR_TASK_BACKGROUND_UNASSIGNED_RGB 1,1,1
+#define COLOR_TASK_BACKGROUND_UNASSIGNED_A 1
+#define COLOR_TASK_BACKGROUND_UNASSIGNED_RGBA COLOR_TASK_BACKGROUND_UNASSIGNED_RGB,COLOR_TASK_BACKGROUND_UNASSIGNED_A
+#define COLOR_TASK_BACKGROUND_ASSIGNED_RGB 1,0.72,0.3
+#define COLOR_TASK_BACKGROUND_ASSIGNED_A 1
+#define COLOR_TASK_BACKGROUND_ASSIGNED_RGBA COLOR_TASK_BACKGROUND_ASSIGNED_RGB,COLOR_TASK_BACKGROUND_ASSIGNED_A
+#define COLOR_TASK_BACKGROUND_CUSTOM_RGB 0.3,0.72,1
+#define COLOR_TASK_BACKGROUND_CUSTOM_A 1
+#define COLOR_TASK_BACKGROUND_CUSTOM_RGBA COLOR_TASK_BACKGROUND_CUSTOM_RGB,COLOR_TASK_BACKGROUND_CUSTOM_A
+
+
+#define COLOR_TASK_TEXT_UNASSIGNED_RGB 0.91,0.91,0.91
+#define COLOR_TASK_TEXT_UNASSIGNED_A 0.55
+#define COLOR_TASK_TEXT_UNASSIGNED_RGBA COLOR_TASK_TEXT_UNASSIGNED_RGB,COLOR_TASK_TEXT_UNASSIGNED_A
+#define COLOR_TASK_TEXT_ASSIGNED_RGB 0.91,0.65,0.27
+#define COLOR_TASK_TEXT_ASSIGNED_A 0.55
+#define COLOR_TASK_TEXT_ASSIGNED_RGBA COLOR_TASK_TEXT_ASSIGNED_RGB,COLOR_TASK_TEXT_ASSIGNED_A
+#define COLOR_TASK_TEXT_CUSTOM_RGB 0.27,0.65,0.91
+#define COLOR_TASK_TEXT_CUSTOM_A 0.55
+#define COLOR_TASK_TEXT_CUSTOM_RGBA COLOR_TASK_TEXT_CUSTOM_RGB,COLOR_TASK_TEXT_CUSTOM_A
+
+
+///////////////////////////////////////////////////////////////////////////
+/// Task colors: generic
+///////////////////////////////////////////////////////////////////////////
+#define COLOR_TASK_UNASSIGNED_RGB COLOR_TASK_BACKGROUND_UNASSIGNED_RGB
+#define COLOR_TASK_UNASSIGNED_RGBA COLOR_TASK_UNASSIGNED_RGB,1
+
+#define COLOR_TASK_ASSIGNED_RGB COLOR_TASK_BACKGROUND_ASSIGNED_RGB
+#define COLOR_TASK_ASSIGNED_RGBA COLOR_TASK_ASSIGNED_RGB,1
+
+#define COLOR_TASK_CUSTOM_RGB COLOR_TASK_BACKGROUND_CUSTOM_RGB
+#define COLOR_TASK_CUSTOM_RGBA COLOR_TASK_CUSTOM_RGB,1
+
+//navigation elements
+#define IGUI_CURSOR_COLOR {COLOR_TASK_TEXT_UNASSIGNED_RGBA}
+
+///////////////////////////////////////////////////////////////////////////
+/// Custom info / Sensors (duplicated in \A3\cfgSensors.hpp !!!)
+///////////////////////////////////////////////////////////////////////////
+
+#define COLOR_SENSORS_RADAR_RGB 0.0,1.0,1.0
+#define COLOR_SENSORS_RADAR_A 1.0
+#define COLOR_SENSORS_RADAR_RGBA {COLOR_SENSORS_RADAR_RGB,COLOR_SENSORS_RADAR_A}
+
+#define COLOR_SENSORS_IR_RGB 1.0,0.0,0.0
+#define COLOR_SENSORS_IR_A 1.0
+#define COLOR_SENSORS_IR_RGBA {COLOR_SENSORS_IR_RGB,COLOR_SENSORS_IR_A}
+
+#define COLOR_SENSORS_RWR_RGB 0.5, 1, 0.5
+#define COLOR_SENSORS_RWR_A 0.5
+#define COLOR_SENSORS_RWR_RGBA {COLOR_SENSORS_RWR_RGB,COLOR_SENSORS_RWR_A}
+
+#define COLOR_SENSORS_NV_RGB 1,1,1
+#define COLOR_SENSORS_NV_A 0
+#define COLOR_SENSORS_NV_RGBA {COLOR_SENSORS_NV_RGB,COLOR_SENSORS_NV_A}
+
+#define COLOR_SENSORS_LAS_RGB 1,1,1
+#define COLOR_SENSORS_LAS_A 0
+#define COLOR_SENSORS_LAS_RGBA {COLOR_SENSORS_LAS_RGB,COLOR_SENSORS_LAS_A}
+
+#define COLOR_SENSORS_VIS_RGB 1.0,1.0,0.5
+#define COLOR_SENSORS_VIS_A 0.8
+#define COLOR_SENSORS_VIS_RGBA {COLOR_SENSORS_VIS_RGB,COLOR_SENSORS_VIS_A}
+
+#define COLOR_SENSORS_MAN_RGB 1.0, 0.5, 1.0
+#define COLOR_SENSORS_MAN_A 1.0
+#define COLOR_SENSORS_MAN_RGBA {COLOR_SENSORS_MAN_RGB,COLOR_SENSORS_MAN_A}
+
+
+#define COLOR_SENSORS_ENEMY_RGB 1.0, 0.0, 0.0
+#define COLOR_SENSORS_ENEMY_A 1.0
+#define COLOR_SENSORS_ENEMY_RGBA {COLOR_SENSORS_ENEMY_RGB,COLOR_SENSORS_ENEMY_A}
+
+#define COLOR_SENSORS_FRIENDLY_RGB 0.0, 1.0, 0.0
+#define COLOR_SENSORS_FRIENDLY_A 1.0
+#define COLOR_SENSORS_FRIENDLY_RGBA {COLOR_SENSORS_FRIENDLY_RGB,COLOR_SENSORS_FRIENDLY_A}
+
+#define COLOR_SENSORS_GROUP_RGB 0.7, 1.0, 0.4
+#define COLOR_SENSORS_GROUP_A 1.0
+#define COLOR_SENSORS_GROUP_RGBA {COLOR_SENSORS_GROUP_RGB,COLOR_SENSORS_GROUP_A}
+
+#define COLOR_SENSORS_WARNING_RGB 1.0, 1.0, 0.0
+#define COLOR_SENSORS_WARNING_A 1.0
+#define COLOR_SENSORS_WARNING_RGBA {COLOR_SENSORS_WARNING_RGB,COLOR_SENSORS_WARNING_A}
+
+#define COLOR_SENSORS_THREAT_RGB 1.0, 0.5, 0.0
+#define COLOR_SENSORS_THREAT_A 1.0
+#define COLOR_SENSORS_THREAT_RGBA {COLOR_SENSORS_THREAT_RGB,COLOR_SENSORS_THREAT_A}
+
+#define COLOR_SENSORS_DEFAULT_RGB 1.0, 1.0, 1.0
+#define COLOR_SENSORS_DEFAULT_A 1.0
+#define COLOR_SENSORS_DEFAULT_RGBA {COLOR_SENSORS_DEFAULT_RGB,COLOR_SENSORS_DEFAULT_A}
\ No newline at end of file
diff --git a/include/a3/ui_f/hpp/defineCommonGrids.inc b/include/a3/ui_f/hpp/defineCommonGrids.inc
new file mode 100644
index 0000000..7772572
--- /dev/null
+++ b/include/a3/ui_f/hpp/defineCommonGrids.inc
@@ -0,0 +1,464 @@
+///////////////////////////////////////////////////////////////////////////
+/// GUI
+///////////////////////////////////////////////////////////////////////////
+
+//--- Hack to avoid too large display upon first startup (fixed in engine)
+//#define GUI_GRID_OLD_WAbs ((safezoneW / ((floor (safezoneW / safezoneH)) max 1)) min 1.2)
+
+//--- New grid for new A3 displays
+#define GUI_GRID_WAbs ((safezoneW / safezoneH) min 1.2)
+#define GUI_GRID_HAbs (GUI_GRID_WAbs / 1.2)
+#define GUI_GRID_W (GUI_GRID_WAbs / 40)
+#define GUI_GRID_H (GUI_GRID_HAbs / 25)
+#define GUI_GRID_X (safezoneX)
+#define GUI_GRID_Y (safezoneY + safezoneH - GUI_GRID_HAbs)
+
+//--- MUF - Test grid used in MP
+#define GUI_GRID_MP_WAbs GUI_GRID_WAbs
+#define GUI_GRID_MP_HAbs GUI_GRID_HAbs
+#define GUI_GRID_MP_W GUI_GRID_W
+#define GUI_GRID_MP_H GUI_GRID_H
+#define GUI_GRID_MP_X (SafezoneX)
+#define GUI_GRID_MP_Y (safezoneY)
+
+//--- Screen Center
+#define GUI_GRID_CENTER_WAbs GUI_GRID_WAbs
+#define GUI_GRID_CENTER_HAbs GUI_GRID_HAbs
+#define GUI_GRID_CENTER_W GUI_GRID_W
+#define GUI_GRID_CENTER_H GUI_GRID_H
+#define GUI_GRID_CENTER_X (safezoneX + (safezoneW - GUI_GRID_CENTER_WAbs)/2)
+#define GUI_GRID_CENTER_Y (safezoneY + (safezoneH - GUI_GRID_CENTER_HAbs)/2)
+
+//--- Bottom center position (used by Revive UI)
+#define GUI_GRID_CENTER_BOTTOM_WAbs GUI_GRID_WAbs
+#define GUI_GRID_CENTER_BOTTOM_HAbs GUI_GRID_HAbs
+#define GUI_GRID_CENTER_BOTTOM_W GUI_GRID_W
+#define GUI_GRID_CENTER_BOTTOM_H GUI_GRID_H
+#define GUI_GRID_CENTER_BOTTOM_X (safezoneX + (safezoneW - GUI_GRID_CENTER_WAbs)/2)
+#define GUI_GRID_CENTER_BOTTOM_Y (safezoneY + safezoneH - GUI_GRID_CENTER_HAbs)
+
+//--- Screen Top Center
+#define GUI_GRID_TOPCENTER_WAbs GUI_GRID_WAbs
+#define GUI_GRID_TOPCENTER_HAbs GUI_GRID_HAbs
+#define GUI_GRID_TOPCENTER_W GUI_GRID_W
+#define GUI_GRID_TOPCENTER_H GUI_GRID_H
+#define GUI_GRID_TOPCENTER_X GUI_GRID_CENTER_X
+#define GUI_GRID_TOPCENTER_Y safezoneY
+
+//--- Screen Bottom Center
+#define GUI_GRID_BOTTOMCENTER_WAbs GUI_GRID_WAbs
+#define GUI_GRID_BOTTOMCENTER_HAbs GUI_GRID_HAbs
+#define GUI_GRID_BOTTOMCENTER_W GUI_GRID_W
+#define GUI_GRID_BOTTOMCENTER_H GUI_GRID_H
+#define GUI_GRID_BOTTOMCENTER_X GUI_GRID_CENTER_X
+#define GUI_GRID_BOTTOMCENTER_Y GUI_GRID_Y
+
+//--- 2D Editor - TEST A3
+#define GUI_GRID_EDITOR_WAbs GUI_GRID_CENTER_WAbs
+#define GUI_GRID_EDITOR_HAbs GUI_GRID_CENTER_HAbs
+#define GUI_GRID_EDITOR_W GUI_GRID_CENTER_W
+#define GUI_GRID_EDITOR_H GUI_GRID_CENTER_H
+#define GUI_GRID_EDITOR_X (safezoneX)
+#define GUI_GRID_EDITOR_Y (safezoneY)
+
+//--- Diary
+#define GUI_GRID_DIARY_WAbs GUI_GRID_WAbs
+#define GUI_GRID_DIARY_HAbs GUI_GRID_HAbs
+#define GUI_GRID_DIARY_W GUI_GRID_W
+#define GUI_GRID_DIARY_H GUI_GRID_H
+#define GUI_GRID_DIARY_X (safezoneX)
+#define GUI_GRID_DIARY_Y (safezoneY)
+
+//--- Top left
+#define GUI_GRID_TOPLEFT_WAbs GUI_GRID_WAbs
+#define GUI_GRID_TOPLEFT_HAbs GUI_GRID_HAbs
+#define GUI_GRID_TOPLEFT_W GUI_GRID_W
+#define GUI_GRID_TOPLEFT_H GUI_GRID_H
+#define GUI_GRID_TOPLEFT_X (safezoneX)
+#define GUI_GRID_TOPLEFT_Y (safezoneY)
+
+
+///////////////////////////////////////////////////////////////////////////
+/// iGUI
+///////////////////////////////////////////////////////////////////////////
+
+//--- IGUI Vehicle
+#define IGUI_GRID_VEHICLE_WAbs (10 * GUI_GRID_W)
+#define IGUI_GRID_VEHICLE_HAbs (4.5 * GUI_GRID_H)
+#define IGUI_GRID_VEHICLE_XDef (safezoneX + 0.5 * GUI_GRID_W)
+#define IGUI_GRID_VEHICLE_YDef (safezoneY + 0.5 * GUI_GRID_H)
+#define IGUI_GRID_VEHICLE_X (profilenamespace getvariable ["IGUI_GRID_VEHICLE_X",IGUI_GRID_VEHICLE_XDef])
+#define IGUI_GRID_VEHICLE_Y (profilenamespace getvariable ["IGUI_GRID_VEHICLE_Y",IGUI_GRID_VEHICLE_YDef])
+#define IGUI_GRID_VEHICLE_W GUI_GRID_W
+#define IGUI_GRID_VEHICLE_H GUI_GRID_H
+
+//--- IGUI Radar
+#define IGUI_GRID_RADAR_WAbs (5.6 * GUI_GRID_W)
+#define IGUI_GRID_RADAR_HAbs (5.6 * GUI_GRID_H)
+#define IGUI_GRID_RADAR_XDef (safezoneX + safezoneW / 2 - 2.8 * GUI_GRID_W)
+#define IGUI_GRID_RADAR_YDef (safezoneY + 0.5 * GUI_GRID_H)
+#define IGUI_GRID_RADAR_X (profilenamespace getvariable ["IGUI_GRID_RADAR_X",IGUI_GRID_RADAR_XDef])
+#define IGUI_GRID_RADAR_Y (profilenamespace getvariable ["IGUI_GRID_RADAR_Y",IGUI_GRID_RADAR_YDef])
+#define IGUI_GRID_RADAR_W GUI_GRID_W
+#define IGUI_GRID_RADAR_H GUI_GRID_H
+
+//--- IGUI Weapon
+#define IGUI_GRID_WEAPON_WAbs (10 * GUI_GRID_W)
+#define IGUI_GRID_WEAPON_HAbs (4.5 * GUI_GRID_H)
+#define IGUI_GRID_WEAPON_XDef ((safezoneX + safezoneW) - IGUI_GRID_WEAPON_WAbs - 4.3 * GUI_GRID_W)
+#define IGUI_GRID_WEAPON_YDef (safezoneY + 0.5 * GUI_GRID_H)
+#define IGUI_GRID_WEAPON_X (profilenamespace getvariable ["IGUI_GRID_WEAPON_X",IGUI_GRID_WEAPON_XDef])
+#define IGUI_GRID_WEAPON_Y (profilenamespace getvariable ["IGUI_GRID_WEAPON_Y",IGUI_GRID_WEAPON_YDef])
+#define IGUI_GRID_WEAPON_W GUI_GRID_W
+#define IGUI_GRID_WEAPON_H GUI_GRID_H
+
+//--- IGUI Stance indicator
+#define IGUI_GRID_STANCE_WAbs (3.7 * GUI_GRID_W)
+#define IGUI_GRID_STANCE_HAbs (3.7 * GUI_GRID_H)
+#define IGUI_GRID_STANCE_XDef ((safezoneX + safezoneW) - IGUI_GRID_STANCE_WAbs - 0.5 * GUI_GRID_W)
+#define IGUI_GRID_STANCE_YDef (safezoneY + 0.5 * GUI_GRID_H)
+#define IGUI_GRID_STANCE_X (profilenamespace getvariable ["IGUI_GRID_STANCE_X",IGUI_GRID_STANCE_XDef])
+#define IGUI_GRID_STANCE_Y (profilenamespace getvariable ["IGUI_GRID_STANCE_Y",IGUI_GRID_STANCE_YDef])
+#define IGUI_GRID_STANCE_W GUI_GRID_W
+#define IGUI_GRID_STANCE_H GUI_GRID_H
+
+//--- IGUI Stamina Bar
+#define IGUI_GRID_STAMINA_WAbs (10 * GUI_GRID_W)
+#define IGUI_GRID_STAMINA_HAbs (1 * GUI_GRID_H)
+#define IGUI_GRID_STAMINA_XDef IGUI_GRID_WEAPON_XDef
+#define IGUI_GRID_STAMINA_YDef (safezoneY + 4.05 * GUI_GRID_H)
+#define IGUI_GRID_STAMINA_X (profilenamespace getvariable ["IGUI_GRID_STAMINA_X",IGUI_GRID_STAMINA_XDef])
+#define IGUI_GRID_STAMINA_Y (profilenamespace getvariable ["IGUI_GRID_STAMINA_Y",IGUI_GRID_STAMINA_YDef])
+#define IGUI_GRID_STAMINA_W GUI_GRID_W
+#define IGUI_GRID_STAMINA_H GUI_GRID_H
+
+//--- IGUI Notification
+#define IGUI_GRID_NOTIFICATION_WAbs (12 * GUI_GRID_W)
+#define IGUI_GRID_NOTIFICATION_HAbs (6 * GUI_GRID_H)
+#define IGUI_GRID_NOTIFICATION_XDef (0.5 - 6 * GUI_GRID_W)
+#define IGUI_GRID_NOTIFICATION_YDef (safezoneY + 6.5 * GUI_GRID_H)
+#define IGUI_GRID_NOTIFICATION_X (profilenamespace getvariable ["IGUI_GRID_NOTIFICATION_X",IGUI_GRID_NOTIFICATION_XDef])
+#define IGUI_GRID_NOTIFICATION_Y (profilenamespace getvariable ["IGUI_GRID_NOTIFICATION_Y",IGUI_GRID_NOTIFICATION_YDef])
+#define IGUI_GRID_NOTIFICATION_W GUI_GRID_W
+#define IGUI_GRID_NOTIFICATION_H GUI_GRID_H
+
+//--- IGUI Action / Command Menu
+#define IGUI_GRID_MENU_WAbs (4.5 * GUI_GRID_W)
+#define IGUI_GRID_MENU_HAbs (13.5 * IGUI_TEXT_SIZE_MEDIUM)
+#define IGUI_GRID_MENU_XDef (1.5 * GUI_GRID_W + safezoneX)
+#define IGUI_GRID_MENU_YDef (5 * GUI_GRID_H + safezoneY)
+#define IGUI_GRID_MENU_X (profilenamespace getvariable ["IGUI_GRID_MENU_X",IGUI_GRID_MENU_XDef])
+#define IGUI_GRID_MENU_Y (profilenamespace getvariable ["IGUI_GRID_MENU_Y",IGUI_GRID_MENU_YDef])
+#define IGUI_GRID_MENU_W GUI_GRID_W
+#define IGUI_GRID_MENU_H GUI_GRID_H
+
+//--- IGUI Communication menu icons
+#define IGUI_GRID_COMM_WAbs (1.5 * GUI_GRID_W)
+#define IGUI_GRID_COMM_HAbs (15 * GUI_GRID_H)
+#define IGUI_GRID_COMM_XDef (0 * GUI_GRID_W + safezoneX)
+#define IGUI_GRID_COMM_YDef (5 * GUI_GRID_H + safezoneY)
+#define IGUI_GRID_COMM_X (profilenamespace getvariable ["IGUI_GRID_COMM_X",IGUI_GRID_COMM_XDef])
+#define IGUI_GRID_COMM_Y (profilenamespace getvariable ["IGUI_GRID_COMM_Y",IGUI_GRID_COMM_YDef])
+#define IGUI_GRID_COMM_W GUI_GRID_W
+#define IGUI_GRID_COMM_H GUI_GRID_H
+
+//--- IGUI Hint
+#define IGUI_GRID_HINT_WAbs (12 * GUI_GRID_W)
+#define IGUI_GRID_HINT_HAbs (8 * GUI_GRID_H)
+#define IGUI_GRID_HINT_XDef ((safezoneX + safezoneW) - IGUI_GRID_HINT_WAbs - 1 * GUI_GRID_W)
+#define IGUI_GRID_HINT_YDef (safezoneY + 6 * GUI_GRID_H)
+#define IGUI_GRID_HINT_X (profilenamespace getvariable ["IGUI_GRID_HINT_X",IGUI_GRID_HINT_XDef])
+#define IGUI_GRID_HINT_Y (profilenamespace getvariable ["IGUI_GRID_HINT_Y",IGUI_GRID_HINT_YDef])
+#define IGUI_GRID_HINT_W GUI_GRID_W
+#define IGUI_GRID_HINT_H GUI_GRID_H
+
+//--- IGUI GPS
+#define IGUI_GRID_GPS_XDef (safezoneX + safezoneW - 11 * GUI_GRID_W)
+#define IGUI_GRID_GPS_YDef (safezoneY + safezoneH - 20.5 * GUI_GRID_H)
+#define IGUI_GRID_GPS_WDef (10 * GUI_GRID_W)
+#define IGUI_GRID_GPS_HDef (10 * GUI_GRID_H)
+#define IGUI_GRID_GPS_X (profilenamespace getvariable ['IGUI_GRID_GPS_X',IGUI_GRID_GPS_XDef])
+#define IGUI_GRID_GPS_Y (profilenamespace getvariable ['IGUI_GRID_GPS_Y',IGUI_GRID_GPS_YDef])
+#define IGUI_GRID_GPS_WAbs (profilenamespace getvariable ['IGUI_GRID_GPS_W',IGUI_GRID_GPS_WDef])
+#define IGUI_GRID_GPS_HAbs (profilenamespace getvariable ['IGUI_GRID_GPS_H',IGUI_GRID_GPS_HDef])
+
+//--- IGUI AV Camera
+#define IGUI_GRID_AVCAMERA_XDef (safezoneX + safezoneW - 11.6 * GUI_GRID_W)
+#define IGUI_GRID_AVCAMERA_YDef (safezoneY + safezoneH - 17.2 * GUI_GRID_H)
+#define IGUI_GRID_AVCAMERA_WDef (10.6 * GUI_GRID_W)
+#define IGUI_GRID_AVCAMERA_HDef (6.7 * GUI_GRID_H)
+#define IGUI_GRID_AVCAMERA_X (profilenamespace getvariable ['IGUI_GRID_AVCAMERA_X',IGUI_GRID_AVCAMERA_XDef])
+#define IGUI_GRID_AVCAMERA_Y (profilenamespace getvariable ['IGUI_GRID_AVCAMERA_Y',IGUI_GRID_AVCAMERA_YDef])
+#define IGUI_GRID_AVCAMERA_WAbs (profilenamespace getvariable ['IGUI_GRID_AVCAMERA_W',IGUI_GRID_AVCAMERA_WDef])
+#define IGUI_GRID_AVCAMERA_HAbs (profilenamespace getvariable ['IGUI_GRID_AVCAMERA_H',IGUI_GRID_AVCAMERA_HDef])
+
+//--- IGUI IGUI Chat Log
+#define IGUI_GRID_CHAT_XDef (safezoneX + 1 * GUI_GRID_W)
+#define IGUI_GRID_CHAT_YDef (safezoneY + safezoneH - 10.5 * GUI_GRID_H)
+#define IGUI_GRID_CHAT_WDef (20 * GUI_GRID_W)
+#define IGUI_GRID_CHAT_HDef (5 * GUI_GRID_H)
+#define IGUI_GRID_CHAT_X (profilenamespace getvariable ["IGUI_GRID_CHAT_X",IGUI_GRID_CHAT_XDef])
+#define IGUI_GRID_CHAT_Y (profilenamespace getvariable ["IGUI_GRID_CHAT_Y",IGUI_GRID_CHAT_YDef])
+#define IGUI_GRID_CHAT_WAbs (profilenamespace getvariable ["IGUI_GRID_CHAT_W",IGUI_GRID_CHAT_WDef])
+#define IGUI_GRID_CHAT_HAbs (profilenamespace getvariable ["IGUI_GRID_CHAT_H",IGUI_GRID_CHAT_HDef])
+
+//--- IGUI Command Bar
+#define IGUI_GRID_BAR_WAbs (36 * GUI_GRID_W)
+#define IGUI_GRID_BAR_HAbs (4 * GUI_GRID_H)
+#define IGUI_GRID_BAR_XDef (safezoneX + 1 * GUI_GRID_W)
+#define IGUI_GRID_BAR_YDef (safezoneY + safezoneH - 4.5 * GUI_GRID_H)
+#define IGUI_GRID_BAR_X (profilenamespace getvariable ["IGUI_GRID_BAR_X",IGUI_GRID_BAR_XDef])
+#define IGUI_GRID_BAR_Y (profilenamespace getvariable ["IGUI_GRID_BAR_Y",IGUI_GRID_BAR_YDef])
+#define IGUI_GRID_BAR_W GUI_GRID_W
+#define IGUI_GRID_BAR_H GUI_GRID_H
+
+//--- IGUI MP Progress
+#define IGUI_GRID_MP_WAbs (2.5 * GUI_GRID_W)
+#define IGUI_GRID_MP_HAbs (15 * GUI_GRID_H)
+#define IGUI_GRID_MP_XDef (safezoneX + safezoneW - 2 * GUI_GRID_W)
+#define IGUI_GRID_MP_YDef (5 * GUI_GRID_H + safezoneY)
+#define IGUI_GRID_MP_X (profilenamespace getvariable ["IGUI_GRID_MP_X",IGUI_GRID_MP_XDef])
+#define IGUI_GRID_MP_Y (profilenamespace getvariable ["IGUI_GRID_MP_Y",IGUI_GRID_MP_YDef])
+#define IGUI_GRID_MP_W GUI_GRID_W
+#define IGUI_GRID_MP_H GUI_GRID_H
+
+//--- IGUI Custom Mission Display
+#define IGUI_GRID_MISSION_WAbs (20 * GUI_GRID_W)
+#define IGUI_GRID_MISSION_HAbs (5 * GUI_GRID_H)
+#define IGUI_GRID_MISSION_XDef (safezoneX + safezoneW - 21 * GUI_GRID_W)
+#define IGUI_GRID_MISSION_YDef (safezoneY + safezoneH - 10.5 * GUI_GRID_H)
+#define IGUI_GRID_MISSION_X (profilenamespace getvariable ["IGUI_GRID_MISSION_X",IGUI_GRID_MISSION_XDef])
+#define IGUI_GRID_MISSION_Y (profilenamespace getvariable ["IGUI_GRID_MISSION_Y",IGUI_GRID_MISSION_YDef])
+#define IGUI_GRID_MISSION_W GUI_GRID_W
+#define IGUI_GRID_MISSION_H GUI_GRID_H
+
+//--- IGUI Custom Info
+#define IGUI_GRID_CUSTOMINFO_WDef (10 * GUI_GRID_W)
+#define IGUI_GRID_CUSTOMINFO_HDef (10 * GUI_GRID_H)
+#define IGUI_GRID_CUSTOMINFOLEFT_XDef (safezoneX + 0.5 * GUI_GRID_W)
+#define IGUI_GRID_CUSTOMINFOLEFT_YDef (safezoneY + safezoneH - 21 * GUI_GRID_H)
+#define IGUI_GRID_CUSTOMINFORIGHT_XDef ((safezoneX + safezoneW) - (IGUI_GRID_CUSTOMINFO_WDef + 0.5 * GUI_GRID_W))
+#define IGUI_GRID_CUSTOMINFORIGHT_YDef (safezoneY + safezoneH - 21 * GUI_GRID_H)
+
+#define IGUI_GRID_CUSTOMINFOLEFT_X (profilenamespace getvariable ["IGUI_GRID_CUSTOMINFOLEFT_X",IGUI_GRID_CUSTOMINFOLEFT_XDef])
+#define IGUI_GRID_CUSTOMINFOLEFT_Y (profilenamespace getvariable ["IGUI_GRID_CUSTOMINFOLEFT_Y",IGUI_GRID_CUSTOMINFOLEFT_YDef])
+#define IGUI_GRID_CUSTOMINFORIGHT_X (profilenamespace getvariable ["IGUI_GRID_CUSTOMINFORIGHT_X",IGUI_GRID_CUSTOMINFORIGHT_XDef])
+#define IGUI_GRID_CUSTOMINFORIGHT_Y (profilenamespace getvariable ["IGUI_GRID_CUSTOMINFORIGHT_Y",IGUI_GRID_CUSTOMINFORIGHT_YDef])
+#define IGUI_GRID_CUSTOMINFO_WAbs (profilenamespace getvariable ["IGUI_GRID_CUSTOMINFORIGHT_W",IGUI_GRID_CUSTOMINFO_WDef])
+#define IGUI_GRID_CUSTOMINFO_HAbs (profilenamespace getvariable ["IGUI_GRID_CUSTOMINFORIGHT_H",IGUI_GRID_CUSTOMINFO_HDef])
+#define IGUI_GRID_CUSTOMINFO_INNER_WAbs IGUI_GRID_CUSTOMINFO_WAbs - 0.25 * GUI_GRID_W
+#define IGUI_GRID_CUSTOMINFO_INNER_HAbs IGUI_GRID_CUSTOMINFO_HAbs - 1.25 * GUI_GRID_H
+
+
+///////////////////////////////////////////////////////////////////////////
+/// Old
+///////////////////////////////////////////////////////////////////////////
+
+//--- Old grid, that is used for old A3 and TKOH displays
+#define GUI_GRID_OLD_WAbs ((safezoneW / safezoneH) min 1.2)
+#define GUI_GRID_OLD_HAbs (GUI_GRID_OLD_WAbs / 1.2)
+#define GUI_GRID_OLD_W (GUI_GRID_OLD_WAbs / 32)
+#define GUI_GRID_OLD_H (GUI_GRID_OLD_HAbs / 20)
+#define GUI_GRID_OLD_X (safezoneX)
+#define GUI_GRID_OLD_Y (safezoneY + safezoneH - GUI_GRID_OLD_HAbs)
+
+//--- Centered
+//#define GUI_GRID_OLD_X (safezoneX + (safezoneW - GUI_GRID_OLD_CENTER_WAbs)/2)
+//--- Dark magic
+//#define GUI_GRID_OLD_X (profilenamespace getvariable ['GUI_GRID_OLD_X',(safezoneX + (safezoneW - GUI_GRID_OLD_CENTER_WAbs)/2)])
+//#define GUI_GRID_OLD_Y (profilenamespace getvariable ['GUI_GRID_OLD_Y',(safezoneY + safezoneH - GUI_GRID_OLD_HAbs)])
+
+//MUF-TEST: Anchor near the right edge of the screen - when changing Interface size, this point doesn't change its X position
+#define GUI_ANCHOR_RIGHT (0.983 * safezoneW + safezoneX)
+#define GUI_ANCHOR_LEFT 0
+
+//--- Screen Center
+#define GUI_GRID_OLD_CENTER_WAbs GUI_GRID_OLD_WAbs
+#define GUI_GRID_OLD_CENTER_HAbs GUI_GRID_OLD_HAbs
+#define GUI_GRID_OLD_CENTER_W GUI_GRID_OLD_W
+#define GUI_GRID_OLD_CENTER_H GUI_GRID_OLD_H
+#define GUI_GRID_OLD_CENTER_X (safezoneX + (safezoneW - GUI_GRID_OLD_CENTER_WAbs)/2)
+#define GUI_GRID_OLD_CENTER_Y (safezoneY + (safezoneH - GUI_GRID_OLD_CENTER_HAbs)/2)
+
+//--- 2D Editor
+#define GUI_GRID_OLD_EDITOR_WAbs GUI_GRID_OLD_CENTER_WAbs
+#define GUI_GRID_OLD_EDITOR_HAbs GUI_GRID_OLD_CENTER_HAbs
+#define GUI_GRID_OLD_EDITOR_W GUI_GRID_OLD_CENTER_W
+#define GUI_GRID_OLD_EDITOR_H GUI_GRID_OLD_CENTER_H
+#define GUI_GRID_OLD_EDITOR_X GUI_GRID_OLD_CENTER_X
+#define GUI_GRID_OLD_EDITOR_Y (safezoneY)
+
+//--- Debug console (center down)
+#define GUI_GRID_OLD_DEBUG_WAbs GUI_GRID_OLD_WAbs
+#define GUI_GRID_OLD_DEBUG_HAbs GUI_GRID_OLD_HAbs
+#define GUI_GRID_OLD_DEBUG_W GUI_GRID_OLD_W
+#define GUI_GRID_OLD_DEBUG_H GUI_GRID_OLD_H
+#define GUI_GRID_OLD_DEBUG_X (safezoneX + (safezoneW - GUI_GRID_OLD_DEBUG_WAbs)/2)
+#define GUI_GRID_OLD_DEBUG_Y (safezoneY + safezoneH - GUI_GRID_OLD_DEBUG_HAbs)
+
+//--- IGUI Common
+#define IGUI_GRID_OLD_WAbs GUI_GRID_OLD_WAbs
+#define IGUI_GRID_OLD_HAbs GUI_GRID_OLD_HAbs
+#define IGUI_GRID_OLD_W GUI_GRID_OLD_W
+#define IGUI_GRID_OLD_H GUI_GRID_OLD_H
+#define IGUI_GRID_OLD_X (safezoneX + (safezoneW - IGUI_GRID_OLD_WAbs) / 2)
+#define IGUI_GRID_OLD_Y (safezoneY + safezoneH - IGUI_GRID_OLD_HAbs)
+
+//--- IGUI Bottom
+#define IGUI_GRID_OLD_BOTTOM_WAbs IGUI_GRID_OLD_WAbs
+#define IGUI_GRID_OLD_BOTTOM_HAbs IGUI_GRID_OLD_HAbs
+#define IGUI_GRID_OLD_BOTTOM_W IGUI_GRID_OLD_W
+#define IGUI_GRID_OLD_BOTTOM_H IGUI_GRID_OLD_H
+#define IGUI_GRID_OLD_BOTTOM_X (safezoneX + (safezoneW - IGUI_GRID_OLD_BOTTOM_WAbs) / 2)
+#define IGUI_GRID_OLD_BOTTOM_Y (safezoneY + safezoneH - IGUI_GRID_OLD_BOTTOM_HAbs)
+
+//--- IGUI Analogue Gauges -----------------------------------------------------------------------------------------------------
+//--- Analogue gauge - Speed
+#define IGUI_GRID_GAUGESPEED_XDef (safezoneX + (safezoneW / 2) - 19.75 * GUI_GRID_W)
+#define IGUI_GRID_GAUGESPEED_YDef (safezoneY + safezoneH - 11.7 * GUI_GRID_H)
+#define IGUI_GRID_GAUGESPEED_X (profilenamespace getvariable ['IGUI_GRID_GAUGESPEED_X',IGUI_GRID_GAUGESPEED_XDef])
+#define IGUI_GRID_GAUGESPEED_Y (profilenamespace getvariable ['IGUI_GRID_GAUGESPEED_Y',IGUI_GRID_GAUGESPEED_YDef])
+#define IGUI_GRID_GAUGESPEED_WAbs (7.5 * GUI_GRID_W)
+#define IGUI_GRID_GAUGESPEED_HAbs (7.5 * GUI_GRID_H)
+
+//--- Analogue gauge - Alt
+#define IGUI_GRID_GAUGEALT_XDef (safezoneX + (safezoneW / 2) - 11.75 * GUI_GRID_W)
+#define IGUI_GRID_GAUGEALT_YDef (safezoneY + safezoneH - 11.7 * GUI_GRID_H)
+#define IGUI_GRID_GAUGEALT_X (profilenamespace getvariable ['IGUI_GRID_GAUGEALT_X',IGUI_GRID_GAUGEALT_XDef])
+#define IGUI_GRID_GAUGEALT_Y (profilenamespace getvariable ['IGUI_GRID_GAUGEALT_Y',IGUI_GRID_GAUGEALT_YDef])
+#define IGUI_GRID_GAUGEALT_WAbs (7.5 * GUI_GRID_W)
+#define IGUI_GRID_GAUGEALT_HAbs (7.5 * GUI_GRID_H)
+
+//--- Analogue gauge - Horizon
+#define IGUI_GRID_GAUGEHORIZON_XDef (safezoneX + ((safezoneW - 7.5 * GUI_GRID_W) / 2))
+#define IGUI_GRID_GAUGEHORIZON_YDef (safezoneY + safezoneH - 11.7 * GUI_GRID_H)
+#define IGUI_GRID_GAUGEHORIZON_X (profilenamespace getvariable ['IGUI_GRID_GAUGEHORIZON_X',IGUI_GRID_GAUGEHORIZON_XDef])
+#define IGUI_GRID_GAUGEHORIZON_Y (profilenamespace getvariable ['IGUI_GRID_GAUGEHORIZON_Y',IGUI_GRID_GAUGEHORIZON_YDef])
+#define IGUI_GRID_GAUGEHORIZON_WAbs (7.5 * GUI_GRID_W)
+#define IGUI_GRID_GAUGEHORIZON_HAbs (7.5 * GUI_GRID_H)
+
+//--- Analogue gauge - Stability
+#define IGUI_GRID_GAUGESTABILITY_XDef (safezoneX + (safezoneW / 2) + 4.25 * GUI_GRID_W)
+#define IGUI_GRID_GAUGESTABILITY_YDef (safezoneY + safezoneH - 11.7 * GUI_GRID_H)
+#define IGUI_GRID_GAUGESTABILITY_X (profilenamespace getvariable ['IGUI_GRID_GAUGESTABILITY_X',IGUI_GRID_GAUGESTABILITY_XDef])
+#define IGUI_GRID_GAUGESTABILITY_Y (profilenamespace getvariable ['IGUI_GRID_GAUGESTABILITY_Y',IGUI_GRID_GAUGESTABILITY_YDef])
+#define IGUI_GRID_GAUGESTABILITY_WAbs (7.5 * GUI_GRID_W)
+#define IGUI_GRID_GAUGESTABILITY_HAbs (7.5 * GUI_GRID_H)
+
+//--- Analogue gauge - Compass
+#define IGUI_GRID_GAUGECOMPASS_XDef (safezoneX + (safezoneW / 2) + 12.25 * GUI_GRID_W)
+#define IGUI_GRID_GAUGECOMPASS_YDef (safezoneY + safezoneH - 11.7 * GUI_GRID_H)
+#define IGUI_GRID_GAUGECOMPASS_X (profilenamespace getvariable ['IGUI_GRID_GAUGECOMPASS_X',IGUI_GRID_GAUGECOMPASS_XDef])
+#define IGUI_GRID_GAUGECOMPASS_Y (profilenamespace getvariable ['IGUI_GRID_GAUGECOMPASS_Y',IGUI_GRID_GAUGECOMPASS_YDef])
+#define IGUI_GRID_GAUGECOMPASS_WAbs (7.5 * GUI_GRID_W)
+#define IGUI_GRID_GAUGECOMPASS_HAbs (7.5 * GUI_GRID_H)
+
+//--- Analogue gauge - Damage indicators
+// #define IGUI_GRID_GAUGEDAMAGE_XDef (safezoneX + (safezoneW / 2) - 19 * GUI_GRID_W)
+// #define IGUI_GRID_GAUGEDAMAGE_YDef (safezoneY + safezoneH - 7 * GUI_GRID_H)
+// #define IGUI_GRID_GAUGEDAMAGE_X (profilenamespace getvariable ['IGUI_GRID_GAUGEDAMAGE_X',IGUI_GRID_GAUGEDAMAGE_XDef])
+// #define IGUI_GRID_GAUGEDAMAGE_Y (profilenamespace getvariable ['IGUI_GRID_GAUGEDAMAGE_Y',IGUI_GRID_GAUGEDAMAGE_YDef])
+// #define IGUI_GRID_GAUGEDAMAGE_WAbs (9.6 * GUI_GRID_W)
+// #define IGUI_GRID_GAUGEDAMAGE_HAbs (2.4 * GUI_GRID_H)
+//--- IGUI Analogue Gauges -----------------------------------------------------------------------------------------------------
+
+//--- Sling Load Assistant
+#define IGUI_GRID_SLINGLOADASSISTANT_XDef (safezoneX + safezoneW - 8 * GUI_GRID_W)
+#define IGUI_GRID_SLINGLOADASSISTANT_YDef (safezoneY + safezoneH - 19.5 * GUI_GRID_H)
+#define IGUI_GRID_SLINGLOADASSISTANT_WDef (7 * GUI_GRID_W)
+#define IGUI_GRID_SLINGLOADASSISTANT_HDef (9.5 * GUI_GRID_H)
+#define IGUI_GRID_SLINGLOADASSISTANT_X (profilenamespace getvariable ['IGUI_GRID_SLINGLOADASSISTANT_X',IGUI_GRID_SLINGLOADASSISTANT_XDef])
+#define IGUI_GRID_SLINGLOADASSISTANT_Y (profilenamespace getvariable ['IGUI_GRID_SLINGLOADASSISTANT_Y',IGUI_GRID_SLINGLOADASSISTANT_YDef])
+#define IGUI_GRID_SLINGLOADASSISTANT_WAbs (profilenamespace getvariable ['IGUI_GRID_SLINGLOADASSISTANT_W',IGUI_GRID_SLINGLOADASSISTANT_WDef])
+#define IGUI_GRID_SLINGLOADASSISTANT_HAbs (profilenamespace getvariable ['IGUI_GRID_SLINGLOADASSISTANT_H',IGUI_GRID_SLINGLOADASSISTANT_HDef])
+
+//--- Squad Radar
+// #define IGUI_GRID_SQUADRADAR_XDef (safezoneX + (safezoneW / 2) - 3 * GUI_GRID_W)
+// #define IGUI_GRID_SQUADRADAR_YDef (safezoneY + safezoneH - 10.9 * GUI_GRID_H)
+// #define IGUI_GRID_SQUADRADAR_X (profilenamespace getvariable ['IGUI_GRID_SQUADRADAR_X',IGUI_GRID_SQUADRADAR_XDef])
+// #define IGUI_GRID_SQUADRADAR_Y (profilenamespace getvariable ['IGUI_GRID_SQUADRADAR_Y',IGUI_GRID_SQUADRADAR_YDef])
+// #define IGUI_GRID_SQUADRADAR_WAbs (6 * GUI_GRID_W)
+// #define IGUI_GRID_SQUADRADAR_HAbs (6 * GUI_GRID_H)
+
+// #define IGUI_GRID_SQUADRADAR_LIST1_XDef (IGUI_GRID_SQUADRADAR_XDef + IGUI_GRID_SQUADRADAR_WAbs)
+// #define IGUI_GRID_SQUADRADAR_LIST1_YDef (IGUI_GRID_SQUADRADAR_YDef)
+// #define IGUI_GRID_SQUADRADAR_LIST1_X (profilenamespace getvariable ['IGUI_GRID_SQUADRADAR_LIST1_X',IGUI_GRID_SQUADRADAR_LIST1_XDef])
+// #define IGUI_GRID_SQUADRADAR_LIST1_Y (profilenamespace getvariable ['IGUI_GRID_SQUADRADAR_LIST1_Y',IGUI_GRID_SQUADRADAR_LIST1_YDef])
+// #define IGUI_GRID_SQUADRADAR_LIST1_WAbs (6 * GUI_GRID_W)
+// #define IGUI_GRID_SQUADRADAR_LIST1_HAbs (6 * GUI_GRID_H)
+
+// #define IGUI_GRID_SQUADRADAR_LIST2_XDef (IGUI_GRID_SQUADRADAR_LIST1_XDef + IGUI_GRID_SQUADRADAR_LIST1_WAbs)
+// #define IGUI_GRID_SQUADRADAR_LIST2_YDef (IGUI_GRID_SQUADRADAR_LIST1_YDef)
+// #define IGUI_GRID_SQUADRADAR_LIST2_X (profilenamespace getvariable ['IGUI_GRID_SQUADRADAR_LIST2_X',IGUI_GRID_SQUADRADAR_LIST2_XDef])
+// #define IGUI_GRID_SQUADRADAR_LIST2_Y (profilenamespace getvariable ['IGUI_GRID_SQUADRADAR_LIST2_Y',IGUI_GRID_SQUADRADAR_LIST2_YDef])
+// #define IGUI_GRID_SQUADRADAR_LIST2_WAbs (6 * GUI_GRID_W)
+// #define IGUI_GRID_SQUADRADAR_LIST2_HAbs (6 * GUI_GRID_H)
+
+//--- IGUI Action / Command Menu
+#define IGUI_GRID_OLD_MENU_WAbs (4.5 * IGUI_GRID_OLD_W)
+#define IGUI_GRID_OLD_MENU_HAbs (10 * (IGUI_TEXT_SIZE_MEDIUM * 1.3))
+#define IGUI_GRID_OLD_MENU_XDef (1 * IGUI_GRID_OLD_W + safezoneX)
+#define IGUI_GRID_OLD_MENU_YDef (5 * IGUI_GRID_OLD_H + safezoneY)
+#define IGUI_GRID_OLD_MENU_X (profilenamespace getvariable ["IGUI_GRID_OLD_MENU_X",IGUI_GRID_OLD_MENU_XDef])
+#define IGUI_GRID_OLD_MENU_Y (profilenamespace getvariable ["IGUI_GRID_OLD_MENU_Y",IGUI_GRID_OLD_MENU_YDef])
+#define IGUI_GRID_OLD_MENU_W IGUI_GRID_OLD_W
+#define IGUI_GRID_OLD_MENU_H IGUI_GRID_OLD_H
+
+//--- E3
+/*
+#define IGUI_GRID_OLD_MENU_WAbs (4.5 * IGUI_GRID_OLD_W)
+#define IGUI_GRID_OLD_MENU_HAbs (10 * (IGUI_TEXT_SIZE_MEDIUM * 1.3))
+#define IGUI_GRID_OLD_MENU_XDef (0.6)
+#define IGUI_GRID_OLD_MENU_YDef (0.55)
+#define IGUI_GRID_OLD_MENU_X (profilenamespace getvariable ["IGUI_GRID_OLD_MENU_X",IGUI_GRID_OLD_MENU_XDef])
+#define IGUI_GRID_OLD_MENU_Y (profilenamespace getvariable ["IGUI_GRID_OLD_MENU_Y",IGUI_GRID_OLD_MENU_YDef])
+#define IGUI_GRID_OLD_MENU_W IGUI_GRID_OLD_W
+#define IGUI_GRID_OLD_MENU_H IGUI_GRID_OLD_H
+*/
+
+//--- IGUI Task
+#define IGUI_GRID_OLD_TASK_WAbs (12 * IGUI_GRID_OLD_W)
+#define IGUI_GRID_OLD_TASK_HAbs (2 * IGUI_GRID_OLD_H)
+#define IGUI_GRID_OLD_TASK_XDef (10 * IGUI_GRID_OLD_W + IGUI_GRID_OLD_X)
+#define IGUI_GRID_OLD_TASK_YDef (1 * IGUI_GRID_OLD_H + safezoneY)
+#define IGUI_GRID_OLD_TASK_X IGUI_GRID_OLD_TASK_XDef
+#define IGUI_GRID_OLD_TASK_Y IGUI_GRID_OLD_TASK_YDef
+#define IGUI_GRID_OLD_TASK_W IGUI_GRID_OLD_W
+#define IGUI_GRID_OLD_TASK_H IGUI_GRID_OLD_H
+
+//--- IGUI PIP
+#define IGUI_GRID_OLD_PIP_XDef (safezoneX + safezoneW - 6.8 * IGUI_GRID_OLD_W)
+#define IGUI_GRID_OLD_PIP_YDef (7 * IGUI_GRID_OLD_H + IGUI_GRID_OLD_Y)
+#define IGUI_GRID_OLD_PIP_WDef (6 * IGUI_GRID_OLD_W)
+#define IGUI_GRID_OLD_PIP_HDef (IGUI_GRID_OLD_PIP_WDef)
+//#define IGUI_GRID_OLD_PIP_X (profilenamespace getvariable ['IGUI_GRID_OLD_PIP_X',IGUI_GRID_OLD_PIP_XDef])
+//#define IGUI_GRID_OLD_PIP_Y (profilenamespace getvariable ['IGUI_GRID_OLD_PIP_Y',IGUI_GRID_OLD_PIP_YDef])
+//#define IGUI_GRID_OLD_PIP_WAbs (profilenamespace getvariable ['IGUI_GRID_OLD_PIP_W',IGUI_GRID_OLD_PIP_WDef])
+#define IGUI_GRID_OLD_PIP_X IGUI_GRID_OLD_PIP_XDef
+#define IGUI_GRID_OLD_PIP_Y IGUI_GRID_OLD_PIP_YDef
+#define IGUI_GRID_OLD_PIP_WAbs IGUI_GRID_OLD_PIP_WDef
+#define IGUI_GRID_OLD_PIP_HAbs (IGUI_GRID_OLD_PIP_WAbs)
+
+
+//--- MUF - experimental optics grid
+// #define GUI_GRID_OLD_OPTICS_X (SafezoneX + ((SafezoneW - SafezoneH) / 2))
+// #define GUI_GRID_OLD_OPTICS_Y (SafezoneY)
+// #define GUI_GRID_OLD_OPTICS_W (0.01875)
+// #define GUI_GRID_OLD_OPTICS_H (0.025)
+// #define GUI_GRID_OLD_OPTICS_WAbs ((SafezoneX + ((SafezoneW - SafezoneH) / 2)) / 0.01875)
+// #define GUI_GRID_OLD_OPTICS_HAbs (SafezoneH / 0.01875)
+
+#define GUI_GRID_OLD_OPTICS_X (SafezoneX + ((SafezoneW - SafezoneH) / 2))
+#define GUI_GRID_OLD_OPTICS_Y (SafezoneY)
+#define GUI_GRID_OLD_OPTICS_W (0.01875 * SafezoneH)
+#define GUI_GRID_OLD_OPTICS_H (0.025 * SafezoneH)
+#define GUI_GRID_OLD_OPTICS_WAbs (SafezoneH)
+#define GUI_GRID_OLD_OPTICS_HAbs (SafezoneH)
+
+//--- MUF - experimental AV Terminal grid
+#define GUI_GRID_OLD_AV_TERMINAL_X (safezoneX)
+#define GUI_GRID_OLD_AV_TERMINAL_Y (safezoneY)
+#define GUI_GRID_OLD_AV_TERMINAL_W (safezoneW / 64)
+#define GUI_GRID_OLD_AV_TERMINAL_H (safezoneH / 40)
+#define GUI_GRID_OLD_AV_TERMINAL_WAbs (safezoneW)
+#define GUI_GRID_OLD_AV_TERMINAL_HAbs (safezoneH)
\ No newline at end of file
diff --git a/mod.cpp b/mod.cpp
index 067dc25..303d9cc 100644
--- a/mod.cpp
+++ b/mod.cpp
@@ -1,7 +1,7 @@
name = "Chat Wheel Redux";
// picture = "logo_cwr_ca.paa";
actionName = "GitHub";
-action = "https://github.com/Dart-Armory/ChatWheel-Redux";
+action = "https://github.com/DartsArmaMods/ChatWheelRedux";
description = "CWR - Version 0.0.0";
// logo = "logo_cwr_ca.paa";
// logoOver = "logo_cwr_over_ca.paa";
diff --git a/optionals/vanillavoice/$PBOPREFIX$ b/optionals/vanillavoice/$PBOPREFIX$
new file mode 100644
index 0000000..c4c46ba
--- /dev/null
+++ b/optionals/vanillavoice/$PBOPREFIX$
@@ -0,0 +1 @@
+z\cwr\addons\vanillavoice
\ No newline at end of file
diff --git a/optionals/vanillavoice/CWR_ChatWheel_VoiceLines.hpp b/optionals/vanillavoice/CWR_ChatWheel_VoiceLines.hpp
new file mode 100644
index 0000000..3f3a559
--- /dev/null
+++ b/optionals/vanillavoice/CWR_ChatWheel_VoiceLines.hpp
@@ -0,0 +1,50 @@
+class CWR_ChatWheel_VoiceLines {
+ class NeedMedic {
+ voiceLines[] = {
+ {CSTRING(NeedMedic_01), 1, 1},
+ {CSTRING(NeedMedic_02), 1, 1},
+ {CSTRING(NeedMedic_03), 1, 1},
+ {CSTRING(NeedMedic_04), 1, 1},
+ {CSTRING(NeedMedic_05), 1, 1},
+ {CSTRING(NeedMedic_06), 1, 1}
+ };
+ };
+ class NeedHelp {
+ voiceLines[] = {
+ {CSTRING(NeedHelp_01), 1, 1},
+ {CSTRING(NeedHelp_02), 1, 1},
+ {CSTRING(NeedHelp_03), 1, 1},
+ {CSTRING(NeedHelp_04), 1, 1},
+ };
+ };
+ class ContactInfantry {
+ voiceLines[] = {
+ {CSTRING(ContactInfantry_01), 1, 1}
+ };
+ };
+ class Unconscious {
+ voiceLines[] = {
+ {CSTRING(Unconscious_01), 1, 1},
+ {CSTRING(Unconscious_02), 1, 1},
+ {CSTRING(Unconscious_03), 1, 1},
+ {CSTRING(Unconscious_04), 1, 1},
+ {CSTRING(Unconscious_05), 1, 1},
+ {CSTRING(Unconscious_06), 1, 1},
+ {CSTRING(Unconscious_07), 1, 1}
+ };
+ };
+
+ class ThrowGrenade {
+ voiceLines[] = {
+ {CSTRING(ThrowGrenade_01), 1, 1},
+ {CSTRING(ThrowGrenade_02), 1, 1},
+ {CSTRING(ThrowGrenade_03), 1, 1}
+ };
+ };
+ class ThrowSmoke {
+ voiceLines[] = {
+ {CSTRING(ThrowSmoke_01), 1, 1},
+ {CSTRING(ThrowSmoke_02), 1, 1}
+ };
+ };
+};
\ No newline at end of file
diff --git a/optionals/vanillavoice/config.cpp b/optionals/vanillavoice/config.cpp
new file mode 100644
index 0000000..3fbc275
--- /dev/null
+++ b/optionals/vanillavoice/config.cpp
@@ -0,0 +1,18 @@
+#include "script_component.hpp"
+
+class CfgPatches {
+ class ADDON {
+ author = AUTHOR;
+ authors[] = {"DartRuffian"};
+ name = COMPONENT_NAME;
+ requiredVersion = REQUIRED_VERSION;
+ requiredAddons[] = {
+ "cwr_chatwheel"
+ };
+ units[] = {};
+ weapons[] = {};
+ VERSION_CONFIG;
+ };
+};
+
+#include "CWR_ChatWheel_VoiceLines.hpp"
\ No newline at end of file
diff --git a/optionals/vanillavoice/script_component.hpp b/optionals/vanillavoice/script_component.hpp
new file mode 100644
index 0000000..ebc29a7
--- /dev/null
+++ b/optionals/vanillavoice/script_component.hpp
@@ -0,0 +1,8 @@
+#define COMPONENT vanillavoice
+#define COMPONENT_BEAUTIFIED Vanilla Voice
+#include "\z\cwr\addons\main\script_mod.hpp"
+
+// #define DEBUG_MODE_FULL
+// #define DISABLE_COMPILE_CACHE
+
+#include "\z\cwr\addons\main\script_macros.hpp"
\ No newline at end of file
diff --git a/optionals/vanillavoice/stringtable.xml b/optionals/vanillavoice/stringtable.xml
new file mode 100644
index 0000000..1945c09
--- /dev/null
+++ b/optionals/vanillavoice/stringtable.xml
@@ -0,0 +1,79 @@
+
+
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthiambadlyhurt.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthiamwounded.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthinjured.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthmedic.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthneedmedicnow.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthwounded.ogg
+
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthineedhelpnow.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthineedsomehelphere.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthneedhelp.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\healthsomebodyhelpme.ogg
+
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\combatcontact\010_vehicles\veh_infantry_p_2.ogg
+
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\heishite.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\mandowne_1.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\mandowne_2.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\mandowne_3.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\wegotamandowne_1.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\wegotamandowne_2.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\normal\140_com_status\wegotamandowne_3.ogg
+
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\combat\200_combatshouts\throwinggrenadee_1.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\combat\200_combatshouts\throwinggrenadee_2.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\combat\200_combatshouts\throwinggrenadee_3.ogg
+
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\combat\200_combatshouts\throwingsmokee_1.ogg
+
+
+ \a3\dubbing_radio_f\data\eng\male01eng\radioprotocoleng\combat\200_combatshouts\throwingsmokee_2.ogg
+
+
+
\ No newline at end of file
diff --git a/tools/config_style_checker.py b/tools/config_style_checker.py
new file mode 100644
index 0000000..5de25ce
--- /dev/null
+++ b/tools/config_style_checker.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python3
+
+import fnmatch
+import os
+import re
+import ntpath
+import sys
+import argparse
+
+def check_config_style(filepath):
+ bad_count_file = 0
+ def pushClosing(t):
+ closingStack.append(closing.expr)
+ closing << Literal( closingFor[t[0]] )
+
+ def popClosing():
+ closing << closingStack.pop()
+
+ reIsClass = re.compile(r'^\s*class(.*)')
+ reIsClassInherit = re.compile(r'^\s*class(.*):')
+ reIsClassBody = re.compile(r'^\s*class(.*){')
+ reBadColon = re.compile(r'\s*class (.*) :')
+ reSpaceAfterColon = re.compile(r'\s*class (.*): ')
+ reSpaceBeforeCurly = re.compile(r'\s*class (.*) {')
+ reClassSingleLine = re.compile(r'\s*class (.*)[{;]')
+
+ with open(filepath, 'r', encoding='utf-8', errors='ignore') as file:
+ content = file.read()
+
+ # Store all brackets we find in this file, so we can validate everything on the end
+ brackets_list = []
+
+ # To check if we are in a comment block
+ isInCommentBlock = False
+ checkIfInComment = False
+ # Used in case we are in a line comment (//)
+ ignoreTillEndOfLine = False
+ # Used in case we are in a comment block (/* */). This is true if we detect a * inside a comment block.
+ # If the next character is a /, it means we end our comment block.
+ checkIfNextIsClosingBlock = False
+
+ # We ignore everything inside a string
+ isInString = False
+ # Used to store the starting type of a string, so we can match that to the end of a string
+ inStringType = '';
+
+ lastIsCurlyBrace = False
+ checkForSemiColumn = False
+
+ # Extra information so we know what line we find errors at
+ lineNumber = 1
+
+ indexOfCharacter = 0
+ # Parse all characters in the content of this file to search for potential errors
+ for c in content:
+ if (lastIsCurlyBrace):
+ lastIsCurlyBrace = False
+ if c == '\n': # Keeping track of our line numbers
+ lineNumber += 1 # so we can print accurate line number information when we detect a possible error
+ if (isInString): # while we are in a string, we can ignore everything else, except the end of the string
+ if (c == inStringType):
+ isInString = False
+ # if we are not in a comment block, we will check if we are at the start of one or count the () {} and []
+ elif (isInCommentBlock == False):
+
+ # This means we have encountered a /, so we are now checking if this is an inline comment or a comment block
+ if (checkIfInComment):
+ checkIfInComment = False
+ if c == '*': # if the next character after / is a *, we are at the start of a comment block
+ isInCommentBlock = True
+ elif (c == '/'): # Otherwise, will check if we are in an line comment
+ ignoreTillEndOfLine = True # and an line comment is a / followed by another / (//) We won't care about anything that comes after it
+
+ if (isInCommentBlock == False):
+ if (ignoreTillEndOfLine): # we are in a line comment, just continue going through the characters until we find an end of line
+ if (c == '\n'):
+ ignoreTillEndOfLine = False
+ else: # validate brackets
+ if (c == '"' or c == "'"):
+ isInString = True
+ inStringType = c
+ elif (c == '/'):
+ checkIfInComment = True
+ elif (c == '('):
+ brackets_list.append('(')
+ elif (c == ')'):
+ if (len(brackets_list) > 0 and brackets_list[-1] in ['{', '[']):
+ print("ERROR: Possible missing round bracket ')' detected at {0} Line number: {1}".format(filepath,lineNumber))
+ bad_count_file += 1
+ brackets_list.append(')')
+ elif (c == '['):
+ brackets_list.append('[')
+ elif (c == ']'):
+ if (len(brackets_list) > 0 and brackets_list[-1] in ['{', '(']):
+ print("ERROR: Possible missing square bracket ']' detected at {0} Line number: {1}".format(filepath,lineNumber))
+ bad_count_file += 1
+ brackets_list.append(']')
+ elif (c == '{'):
+ brackets_list.append('{')
+ elif (c == '}'):
+ lastIsCurlyBrace = True
+ if (len(brackets_list) > 0 and brackets_list[-1] in ['(', '[']):
+ print("ERROR: Possible missing curly brace '}}' detected at {0} Line number: {1}".format(filepath,lineNumber))
+ bad_count_file += 1
+ brackets_list.append('}')
+ elif (c== '\t'):
+ print("ERROR: Tab detected at {0} Line number: {1}".format(filepath,lineNumber))
+ bad_count_file += 1
+
+ else: # Look for the end of our comment block
+ if (c == '*'):
+ checkIfNextIsClosingBlock = True;
+ elif (checkIfNextIsClosingBlock):
+ if (c == '/'):
+ isInCommentBlock = False
+ elif (c != '*'):
+ checkIfNextIsClosingBlock = False
+ indexOfCharacter += 1
+
+ if brackets_list.count('[') != brackets_list.count(']'):
+ print("ERROR: A possible missing square bracket [ or ] in file {0} [ = {1} ] = {2}".format(filepath,brackets_list.count('['),brackets_list.count(']')))
+ bad_count_file += 1
+ if brackets_list.count('(') != brackets_list.count(')'):
+ print("ERROR: A possible missing round bracket ( or ) in file {0} ( = {1} ) = {2}".format(filepath,brackets_list.count('('),brackets_list.count(')')))
+ bad_count_file += 1
+ if brackets_list.count('{') != brackets_list.count('}'):
+ print("ERROR: A possible missing curly brace {{ or }} in file {0} {{ = {1} }} = {2}".format(filepath,brackets_list.count('{'),brackets_list.count('}')))
+ bad_count_file += 1
+
+ file.seek(0)
+ for lineNumber, line in enumerate(file.readlines()):
+ if reIsClass.match(line):
+ if reBadColon.match(line):
+ print(f"WARNING: bad class colon {filepath} Line number: {lineNumber+1}")
+ # bad_count_file += 1
+ if reIsClassInherit.match(line):
+ if not reSpaceAfterColon.match(line):
+ print(f"WARNING: bad class missing space after colon {filepath} Line number: {lineNumber+1}")
+ if reIsClassBody.match(line):
+ if not reSpaceBeforeCurly.match(line):
+ print(f"WARNING: bad class inherit missing space before curly braces {filepath} Line number: {lineNumber+1}")
+ if not reClassSingleLine.match(line):
+ print(f"WARNING: bad class braces placement {filepath} Line number: {lineNumber+1}")
+ # bad_count_file += 1
+
+ return bad_count_file
+
+def main():
+
+ print("Validating Config Style")
+
+ sqf_list = []
+ bad_count = 0
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default="")
+ args = parser.parse_args()
+
+ for folder in ['addons', 'optionals']:
+ # Allow running from root directory as well as from inside the tools directory
+ rootDir = "../" + folder
+ if (os.path.exists(folder)):
+ rootDir = folder
+
+ for root, dirnames, filenames in os.walk(rootDir + '/' + args.module):
+ for filename in fnmatch.filter(filenames, '*.cpp'):
+ sqf_list.append(os.path.join(root, filename))
+ for filename in fnmatch.filter(filenames, '*.hpp'):
+ sqf_list.append(os.path.join(root, filename))
+ for filename in fnmatch.filter(filenames, '*.rvmat'):
+ sqf_list.append(os.path.join(root, filename))
+ for filename in fnmatch.filter(filenames, '*.cfg'):
+ sqf_list.append(os.path.join(root, filename))
+
+ for filename in sqf_list:
+ bad_count = bad_count + check_config_style(filename)
+
+ print("------\nChecked {0} files\nErrors detected: {1}".format(len(sqf_list), bad_count))
+ if (bad_count == 0):
+ print("Config validation PASSED")
+ else:
+ print("Config validation FAILED")
+
+ return bad_count
+
+if __name__ == "__main__":
+ sys.exit(main())
\ No newline at end of file
diff --git a/tools/release.bat b/tools/release.bat
new file mode 100644
index 0000000..659a699
--- /dev/null
+++ b/tools/release.bat
@@ -0,0 +1,4 @@
+@ECHO off
+hemtt script update_build.rhai
+hemtt script update_minor.rhai
+hemtt release
\ No newline at end of file
diff --git a/tools/release_patch.bat b/tools/release_patch.bat
new file mode 100644
index 0000000..ffeab9b
--- /dev/null
+++ b/tools/release_patch.bat
@@ -0,0 +1,4 @@
+@ECHO off
+hemtt script update_build.rhai
+hemtt script update_patch.rhai
+hemtt release
\ No newline at end of file