diff --git a/framework/CfgFunctions.hpp b/framework/CfgFunctions.hpp
index d19b024..76ade6b 100644
--- a/framework/CfgFunctions.hpp
+++ b/framework/CfgFunctions.hpp
@@ -1,4 +1,6 @@
-class milsim
+#include "script_mod.hpp"
+
+class PREFIX
{
class settings
{
@@ -11,7 +13,7 @@ class milsim
class init
{
- file = "framework\init";
+ file = "framework\init\functions";
class initServer { postInit = 1;}; //needs refactor
class initPlayerLocal { postInit = 1;};
};
@@ -71,9 +73,9 @@ class milsim
};
};
-class milsim_util {
+class DOUBLES(PREFIX,util) {
class functions {
- file = "framework\util";
+ file = "framework\util\functions";
class logMissionInfo { postInit = 1; };
class addPlayerInfoToArray {};
class log {};
@@ -85,7 +87,7 @@ class milsim_util {
};
};
-class milsim_resupply {
+class DOUBLES(PREFIX,resupply) {
class functions {
file = "framework\resupply\functions";
class init {postInit=1;};
@@ -96,30 +98,25 @@ class milsim_resupply {
};
};
-class milsim_fbcb2_assets {
+class DOUBLES(PREFIX,fbcb2_assets) {
class functions {
- file = "framework\fbcb2\assets";
+ file = "framework\fbcb2_assets\functions";
+ class init {postInit=1;};
class updateAssetDiary {};
class removeAssetDiaryRecords {};
class getMagsForWeapon {};
class getWeaponry {};
class getInventory {};
class getVehicleData {};
- };
- class assetsByBase {
- file = "framework\fbcb2\assets\byBase";
class getAssetsByBase {};
class getStartingAssetsByBase {};
class updateAssetsByBase {};
- };
- class markers {
- file = "framework\fbcb2\assets\markers";
class showMarkersOnMap {};
class removeMarkersOnMap {};
};
};
-class milsim_vehicleFlags {
+class DOUBLES(PREFIX,vehicleFlags) {
class functions {
file = "framework\vehicleFlags\functions";
class init {postInit=1;};
@@ -129,7 +126,7 @@ class milsim_vehicleFlags {
};
};
-class milsim_reinsert {
+class DOUBLES(PREFIX,reinsert) {
class server {
file = "framework\reinsert\server";
class initServer { postInit = 1; };
diff --git a/framework/fbcb2_assets/functions/fn_addCBASettings.sqf b/framework/fbcb2_assets/functions/fn_addCBASettings.sqf
new file mode 100644
index 0000000..5964caf
--- /dev/null
+++ b/framework/fbcb2_assets/functions/fn_addCBASettings.sqf
@@ -0,0 +1,27 @@
+#include "..\script_component.hpp"
+
+//---------------------
+// Asset Diary and Markers Settings
+
+[
+ QGVAR(setting_detectionRangeFromBase), // variable
+ "SLIDER", // type
+ ["Detection Range From Base", "The range from a base that assets will be detected"], // title
+ [QUOTE(SETTINGS_GROUP_NAME), QUOTE(COMPONENT_BEAUTIFIED)], // category
+ [0, 1000, 750, 0, false], // [_min, _max, _default, _trailingDecimals, _isPercentage]
+ true, // global setting
+ {
+ params ["_value"];
+ [
+ "fbcb2_assets",
+ "SETTING CHANGED",
+ [
+ [
+ "setting",
+ "milsim_fbcb2_assets_setting_detectionRangeFromBase"
+ ],
+ ["newValue", _value]
+ ]
+ ] call milsim_util_fnc_log;
+ }
+] call CBA_fnc_addSetting;
\ No newline at end of file
diff --git a/framework/fbcb2/assets/byBase/fn_getAssetsByBase.sqf b/framework/fbcb2_assets/functions/fn_getAssetsByBase.sqf
similarity index 100%
rename from framework/fbcb2/assets/byBase/fn_getAssetsByBase.sqf
rename to framework/fbcb2_assets/functions/fn_getAssetsByBase.sqf
diff --git a/framework/fbcb2/assets/fn_getInventory.sqf b/framework/fbcb2_assets/functions/fn_getInventory.sqf
similarity index 100%
rename from framework/fbcb2/assets/fn_getInventory.sqf
rename to framework/fbcb2_assets/functions/fn_getInventory.sqf
diff --git a/framework/fbcb2/assets/fn_getMagsForWeapon.sqf b/framework/fbcb2_assets/functions/fn_getMagsForWeapon.sqf
similarity index 100%
rename from framework/fbcb2/assets/fn_getMagsForWeapon.sqf
rename to framework/fbcb2_assets/functions/fn_getMagsForWeapon.sqf
diff --git a/framework/fbcb2/assets/byBase/fn_getStartingAssetsByBase.sqf b/framework/fbcb2_assets/functions/fn_getStartingAssetsByBase.sqf
similarity index 100%
rename from framework/fbcb2/assets/byBase/fn_getStartingAssetsByBase.sqf
rename to framework/fbcb2_assets/functions/fn_getStartingAssetsByBase.sqf
diff --git a/framework/fbcb2/assets/fn_getVehicleData.sqf b/framework/fbcb2_assets/functions/fn_getVehicleData.sqf
similarity index 100%
rename from framework/fbcb2/assets/fn_getVehicleData.sqf
rename to framework/fbcb2_assets/functions/fn_getVehicleData.sqf
diff --git a/framework/fbcb2/assets/fn_getWeaponry.sqf b/framework/fbcb2_assets/functions/fn_getWeaponry.sqf
similarity index 100%
rename from framework/fbcb2/assets/fn_getWeaponry.sqf
rename to framework/fbcb2_assets/functions/fn_getWeaponry.sqf
diff --git a/framework/fbcb2_assets/functions/fn_initClient.sqf b/framework/fbcb2_assets/functions/fn_initClient.sqf
new file mode 100644
index 0000000..28f1103
--- /dev/null
+++ b/framework/fbcb2_assets/functions/fn_initClient.sqf
@@ -0,0 +1,9 @@
+#include "..\script_component.hpp"
+
+if (!hasInterface) exitWith {};
+
+// once the server has published that assets have been gathered and distributed to bases (respawn modules),
+// we can update the asset diary on our end using that data
+[{missionNamespace getVariable [QGVAR(serverAssetsReady), false]}, {
+ call FUNC(updateAssetDiary);
+}] call CBA_fnc_waitUntilAndExecute;
diff --git a/framework/fbcb2_assets/functions/fn_initServer.sqf b/framework/fbcb2_assets/functions/fn_initServer.sqf
new file mode 100644
index 0000000..70acbed
--- /dev/null
+++ b/framework/fbcb2_assets/functions/fn_initServer.sqf
@@ -0,0 +1,23 @@
+#include "..\script_component.hpp"
+
+if (!isServer) exitWith {};
+
+// init asset stores at bases
+[true] call FUNC(updateAssetsByBase);
+
+missionNamespace setVariable [QGVAR(serverAssetsReady), true, true];
+
+// starting 5 minutes after postInit, update asset stores every 5 minutes
+[{
+ [
+ {[false] call FUNC(updateAssetsByBase);},
+ 60*5
+ ] call CBA_fnc_addPerFrameHandler;
+}, 60*5] call CBA_fnc_waitAndExecute;
+
+
+// add end mission EH
+addMissionEventHandler ["MPEnded", {
+ // log the "current" asset counts to RPT
+ [false, true] call FUNC(updateAssetsByBase);
+}];
\ No newline at end of file
diff --git a/framework/fbcb2/assets/fn_removeAssetDiaryRecords.sqf b/framework/fbcb2_assets/functions/fn_removeAssetDiaryRecords.sqf
similarity index 100%
rename from framework/fbcb2/assets/fn_removeAssetDiaryRecords.sqf
rename to framework/fbcb2_assets/functions/fn_removeAssetDiaryRecords.sqf
diff --git a/framework/fbcb2/assets/markers/fn_removeMarkersOnMap.sqf b/framework/fbcb2_assets/functions/fn_removeMarkersOnMap.sqf
similarity index 100%
rename from framework/fbcb2/assets/markers/fn_removeMarkersOnMap.sqf
rename to framework/fbcb2_assets/functions/fn_removeMarkersOnMap.sqf
diff --git a/framework/fbcb2/assets/markers/fn_showMarkersOnMap.sqf b/framework/fbcb2_assets/functions/fn_showMarkersOnMap.sqf
similarity index 100%
rename from framework/fbcb2/assets/markers/fn_showMarkersOnMap.sqf
rename to framework/fbcb2_assets/functions/fn_showMarkersOnMap.sqf
diff --git a/framework/fbcb2/assets/fn_updateAssetDiary.sqf b/framework/fbcb2_assets/functions/fn_updateAssetDiary.sqf
similarity index 81%
rename from framework/fbcb2/assets/fn_updateAssetDiary.sqf
rename to framework/fbcb2_assets/functions/fn_updateAssetDiary.sqf
index 0f87ef2..c96fab8 100644
--- a/framework/fbcb2/assets/fn_updateAssetDiary.sqf
+++ b/framework/fbcb2_assets/functions/fn_updateAssetDiary.sqf
@@ -1,16 +1,17 @@
+#include "..\script_component.hpp"
+
if (!hasInterface) exitWith {};
// create diary records
-
// remove any existing asset map markers
-call milsim_fbcb2_assets_fnc_removeMarkersOnMap;
+call FUNC(removeMarkersOnMap);
// remove existing asset records
-call milsim_fbcb2_assets_fnc_removeAssetDiaryRecords;
+call FUNC(removeAssetDiaryRecords);
// get all vehicles by base
-private _vehiclesByBase = call milsim_fbcb2_assets_fnc_getAssetsByBase;
+private _vehiclesByBase = call FUNC(getAssetsByBase);
if (count _vehiclesByBase isEqualTo 0) exitWith {false};
// put vehicles from each base into a single array
@@ -38,7 +39,7 @@ private _distinctVehiclesClassNames = [];
private _vehicleCfg = configOf _representativeVehicle;
private _vehicleCallsign = toUpper (
_representativeVehicle getVariable [
- "milsim_fbcb2_assets_callsign",
+ QGVAR(callsign),
"NONE ASSIGNED"
]
);
@@ -51,7 +52,7 @@ private _distinctVehiclesClassNames = [];
) then {continue};
// Get the vehicle data
- private _processed = [_representativeVehicle] call milsim_fbcb2_assets_fnc_getVehicleData;
+ private _processed = [_representativeVehicle] call FUNC(getVehicleData);
if (isNil "_processed") then {continue};
_processed params ["_vehicleCfg", "_displayName", "_diaryTextSections"];
@@ -113,7 +114,7 @@ private _distinctVehiclesClassNames = [];
// Link to show markers
private _showMarkersText = format[
- "SHOW MARKERS at vehicle positions (in %5)",
+ "SHOW MARKERS at vehicle positions (in %5)",
_className,
_markerType,
_randomColor#0,
@@ -125,10 +126,10 @@ private _distinctVehiclesClassNames = [];
_recordText pushBack _showMarkersText;
// Link to hide markers
- _recordText pushBack "REMOVE ALL MARKERS showing asset positions";
+ _recordText pushBack "REMOVE ALL MARKERS showing asset positions";
// Link to update asset diary entries
- _recordText pushBack "UPDATE ENTRIES for all assets";
+ _recordText pushBack "UPDATE ENTRIES for all assets";
_recordText pushBack format[
"%1",
@@ -148,13 +149,13 @@ private _distinctVehiclesClassNames = [];
private _subjectID = "";
switch (true) do {
case (_representativeVehicle isKindOf "Helicopter"): {
- _subjectID = milsim_fbcb2_subjectAssetsRotaryID;
+ _subjectID = EGVAR(fbcb2,subjectAssetsRotaryID);
};
case (_representativeVehicle isKindOf "Air"): {
- _subjectID = milsim_fbcb2_subjectAssetsFixedWingID;
+ _subjectID = EGVAR(fbcb2,subjectAssetsFixedWingID);
};
default {
- _subjectID = milsim_fbcb2_subjectAssetsGroundID;
+ _subjectID = EGVAR(fbcb2,subjectAssetsGroundID);
};
};
@@ -174,12 +175,12 @@ private _distinctVehiclesClassNames = [];
// log to RPT
[
- "fbcb2_assets",
+ QUOTE(COMPONENT),
"UPDATED ASSET DIARY",
[
["assetCount", count _vehicles],
["distinctAssetCount", count _distinctVehiclesClassNames]
]
-] call milsim_util_fnc_log;
+] call EFUNC(util,log);
true;
\ No newline at end of file
diff --git a/framework/fbcb2/assets/byBase/fn_updateAssetsByBase.sqf b/framework/fbcb2_assets/functions/fn_updateAssetsByBase.sqf
similarity index 89%
rename from framework/fbcb2/assets/byBase/fn_updateAssetsByBase.sqf
rename to framework/fbcb2_assets/functions/fn_updateAssetsByBase.sqf
index d5f5ffb..23fdef5 100644
--- a/framework/fbcb2/assets/byBase/fn_updateAssetsByBase.sqf
+++ b/framework/fbcb2_assets/functions/fn_updateAssetsByBase.sqf
@@ -1,3 +1,5 @@
+#include "..\script_component.hpp"
+
params [
["_isInit", false, [false]],
["_logCurrentAssets", false, [false]]
@@ -12,8 +14,8 @@ if (!isServer) exitWith {};
private _allVehicles = vehicles;
private _allSaved = [];
-private _assetsAtThisBaseVar = "milsim_fbcb2_assets_assetsAtThisBase";
-private _assetsStartedAtThisBaseVar = "milsim_fbcb2_assets_assetsStartedAtThisBase";
+private _assetsAtThisBaseVar = QGVAR(assetsAtThisBase);
+private _assetsStartedAtThisBaseVar = QGVAR(assetsStartedAtThisBase);
{
private _className = configName _x;
@@ -23,7 +25,7 @@ private _assetsStartedAtThisBaseVar = "milsim_fbcb2_assets_assetsStartedAtThisBa
private _asset = _x;
// avoid duplicates
if (_asset in _allSaved) then {continue};
- private _closestBase = [_asset] call milsim_util_fnc_getNearestBase;
+ private _closestBase = [_asset] call EFUNC(util,getNearestBase);
if (isNull _closestBase) then {
// no base found
continue;
@@ -36,7 +38,7 @@ private _assetsStartedAtThisBaseVar = "milsim_fbcb2_assets_assetsStartedAtThisBa
continue;
};
- _asset setVariable ["milsim_fbcb2_assets_callsign", _callsign, true];
+ _asset setVariable [QGVAR(callsign), _callsign, true];
// add to base's assets list
private _baseAssets = _closestBase getVariable [_assetsAtThisBaseVar, []];
@@ -66,7 +68,7 @@ private _assetsStartedAtThisBaseVar = "milsim_fbcb2_assets_assetsStartedAtThisBa
// avoid duplicates
if (_asset in _allSaved) then {continue};
- private _closestBase = [_asset] call milsim_util_fnc_getNearestBase;
+ private _closestBase = [_asset] call EFUNC(util,getNearestBase);
if (isNull _closestBase) then {
// no base found
continue;
@@ -74,7 +76,7 @@ private _assetsStartedAtThisBaseVar = "milsim_fbcb2_assets_assetsStartedAtThisBa
if (
_asset distance _closestBase >
- milsim_fbcb2_assets_setting_detectionRangeFromBase
+ GVAR(setting_detectionRangeFromBase)
) then {
// not within range
continue;
@@ -132,7 +134,7 @@ if !(_isInit || _logCurrentAssets) exitWith {};
private _asset = _x;
[
["callsign", _asset getVariable [
- "milsim_fbcb2_assets_callsign",
+ QGVAR(callsign),
"N/A"
]],
["className", typeOf _asset],
diff --git a/framework/fbcb2_assets/script_component.hpp b/framework/fbcb2_assets/script_component.hpp
new file mode 100644
index 0000000..c5a24ae
--- /dev/null
+++ b/framework/fbcb2_assets/script_component.hpp
@@ -0,0 +1,3 @@
+#define COMPONENT fbcb2_assets
+#define COMPONENT_BEAUTIFIED FBCB2 - Assets
+#include "../script_mod.hpp"
\ No newline at end of file
diff --git a/framework/init/fn_initServer.sqf b/framework/init/fn_initServer.sqf
deleted file mode 100644
index d70c518..0000000
--- a/framework/init/fn_initServer.sqf
+++ /dev/null
@@ -1,35 +0,0 @@
-if (!isServer) exitWith {};
-
-milsim_baseObjects = allMissionObjects "ModuleRespawnPosition_F";
-publicVariable "milsim_baseObjects";
-
-// init asset stores at bases
-[true] call milsim_fbcb2_assets_fnc_updateAssetsByBase;
-// starting 5 minutes after postInit, update asset stores every 5 minutes
-[{
- [
- {[false] call milsim_fbcb2_assets_fnc_updateAssetsByBase;},
- 60*5
- ] call CBA_fnc_addPerFrameHandler;
-}, 60*5] call CBA_fnc_waitAndExecute;
-
-// add end mission EH
-addMissionEventHandler ["MPEnded", {
- // log the "current" asset counts to RPT
- [false, true] call milsim_fbcb2_assets_fnc_updateAssetsByBase;
-}];
-
-// Initializes the Dynamic Groups framework and groups
-["Initialize", [true]] call BIS_fnc_dynamicGroups;
-
-["milsim_logText", {
- params [["_strArray", [""], [[]]]];
- {
- diag_log text _x;
- } forEach _strArray;
-}] call CBA_fnc_addEventHandler;
-
-missionNamespace setVariable ["milsim_complete", true];
-diag_log text "[MILSIM] (initServer) milsim_complete: version 2.3";
-
-publicVariable "milsim_complete";
diff --git a/framework/init/fn_initPlayerLocal.sqf b/framework/init/functions/fn_initPlayerLocal.sqf
similarity index 100%
rename from framework/init/fn_initPlayerLocal.sqf
rename to framework/init/functions/fn_initPlayerLocal.sqf
diff --git a/framework/init/functions/fn_initServer.sqf b/framework/init/functions/fn_initServer.sqf
new file mode 100644
index 0000000..5ad0adf
--- /dev/null
+++ b/framework/init/functions/fn_initServer.sqf
@@ -0,0 +1,26 @@
+#include "..\script_component.hpp"
+
+if (!isServer) exitWith {};
+
+milsim_baseObjects = allMissionObjects "ModuleRespawnPosition_F";
+publicVariable "milsim_baseObjects";
+
+// Initializes the Dynamic Groups framework and groups
+["Initialize", [true]] call BIS_fnc_dynamicGroups;
+
+["milsim_logText", {
+ params [["_strArray", [""], [[]]]];
+ {
+ diag_log text _x;
+ } forEach _strArray;
+}] call CBA_fnc_addEventHandler;
+
+missionNamespace setVariable [QGVARMAIN(complete), true];
+
+[
+ QUOTE(COMPONENT),
+ format["%1: version %2", QGVARMAIN(complete), QUOTE(VERSION_STR)],
+ [["version", QUOTE(VERSION_STR)]]
+] call EFUNC(util,log);
+
+publicVariable "milsim_complete";
diff --git a/framework/init/script_component.hpp b/framework/init/script_component.hpp
new file mode 100644
index 0000000..fedab82
--- /dev/null
+++ b/framework/init/script_component.hpp
@@ -0,0 +1,3 @@
+#define COMPONENT init
+#define COMPONENT_BEAUTIFIED Init
+#include "../script_mod.hpp"
\ No newline at end of file
diff --git a/framework/settings/fn_addCBASettings.sqf b/framework/settings/fn_addCBASettings.sqf
index ce3a11a..6e4a56e 100644
--- a/framework/settings/fn_addCBASettings.sqf
+++ b/framework/settings/fn_addCBASettings.sqf
@@ -242,32 +242,6 @@
}
] call CBA_fnc_addSetting;
-//---------------------
-// Asset Diary and Markers Settings
-
-[
- "milsim_fbcb2_assets_setting_detectionRangeFromBase", // variable
- "SLIDER", // type
- ["Detection Range From Base", "The range from a base that assets will be detected"], // title
- ["17th Battalion", "Asset Diary and Markers"], // category
- [0, 1000, 750, 0, false], // [_min, _max, _default, _trailingDecimals, _isPercentage]
- true, // global setting
- {
- params ["_value"];
- [
- "fbcb2_assets",
- "SETTING CHANGED",
- [
- [
- "setting",
- "milsim_fbcb2_assets_setting_detectionRangeFromBase"
- ],
- ["newValue", _value]
- ]
- ] call milsim_util_fnc_log;
- }
-] call CBA_fnc_addSetting;
-
diag_log text "[MILSIM] (settings) Custom CBA settings initialized";
nil;
\ No newline at end of file
diff --git a/framework/util/fn_addPlayerInfoToArray.sqf b/framework/util/functions/fn_addPlayerInfoToArray.sqf
similarity index 88%
rename from framework/util/fn_addPlayerInfoToArray.sqf
rename to framework/util/functions/fn_addPlayerInfoToArray.sqf
index 4a473df..3035094 100644
--- a/framework/util/fn_addPlayerInfoToArray.sqf
+++ b/framework/util/functions/fn_addPlayerInfoToArray.sqf
@@ -1,3 +1,5 @@
+#include "..\script_component.hpp"
+
params [["_playerObj", objNull], ["_arrayToModify", [], [[]]]];
if (isNull _playerObj) exitWith {_arrayToModify};
diff --git a/framework/util/fn_getBattalionCfg.sqf b/framework/util/functions/fn_getBattalionCfg.sqf
similarity index 100%
rename from framework/util/fn_getBattalionCfg.sqf
rename to framework/util/functions/fn_getBattalionCfg.sqf
diff --git a/framework/util/fn_getNameOfBase.sqf b/framework/util/functions/fn_getNameOfBase.sqf
similarity index 89%
rename from framework/util/fn_getNameOfBase.sqf
rename to framework/util/functions/fn_getNameOfBase.sqf
index 81ed4ec..c0d56e8 100644
--- a/framework/util/fn_getNameOfBase.sqf
+++ b/framework/util/functions/fn_getNameOfBase.sqf
@@ -1,3 +1,5 @@
+#include "..\script_component.hpp"
+
params [["_base", objNull, [objNull]]];
if (_base == objNull) exitWith {""};
diff --git a/framework/util/fn_getNearestBase.sqf b/framework/util/functions/fn_getNearestBase.sqf
similarity index 87%
rename from framework/util/fn_getNearestBase.sqf
rename to framework/util/functions/fn_getNearestBase.sqf
index 68b103c..4dfc208 100644
--- a/framework/util/fn_getNearestBase.sqf
+++ b/framework/util/functions/fn_getNearestBase.sqf
@@ -1,3 +1,5 @@
+#include "..\script_component.hpp"
+
params [["_object", objNull, [objNull]]];
if (isNull _object) exitWith {objNull};
diff --git a/framework/util/fn_log.sqf b/framework/util/functions/fn_log.sqf
similarity index 76%
rename from framework/util/fn_log.sqf
rename to framework/util/functions/fn_log.sqf
index 2df2574..80639e0 100644
--- a/framework/util/fn_log.sqf
+++ b/framework/util/functions/fn_log.sqf
@@ -9,6 +9,7 @@
1: STRING - message to log.
2: ARRAY - Key value pairs of data to log.
*/
+#include "..\script_component.hpp"
params [
["_component", "", [""]],
@@ -23,6 +24,6 @@ _message regexReplace ["\[", "("];
_message regexReplace ["\]", ")"];
private _json = [_hash] call CBA_fnc_encodeJSON;
-_log = format ["[milsim] [%1] [%2] [%3] :: %4", _component, _fnc_scriptNameParent, _message, _json];
+_log = format ["[%1] [%2] [%3] [%4] :: %5", QUOTE(PREFIX), _component, _fnc_scriptNameParent, _message, _json];
diag_log text _log;
\ No newline at end of file
diff --git a/framework/util/fn_logMissionInfo.sqf b/framework/util/functions/fn_logMissionInfo.sqf
similarity index 92%
rename from framework/util/fn_logMissionInfo.sqf
rename to framework/util/functions/fn_logMissionInfo.sqf
index d2c1364..1da141c 100644
--- a/framework/util/fn_logMissionInfo.sqf
+++ b/framework/util/functions/fn_logMissionInfo.sqf
@@ -1,5 +1,7 @@
+#include "..\script_component.hpp"
+
[
- "init",
+ QUOTE(COMPONENT),
"MISSION INFO",
[
["serverName", serverName],
@@ -20,4 +22,4 @@
["LOGIC", playableSlotsNumber sideLogic] // 5 is LOGIC side
]]
]
-] call milsim_util_fnc_log;
\ No newline at end of file
+] call FUNC(log);
\ No newline at end of file
diff --git a/framework/util/fn_padString.sqf b/framework/util/functions/fn_padString.sqf
similarity index 92%
rename from framework/util/fn_padString.sqf
rename to framework/util/functions/fn_padString.sqf
index e5d3faf..f387ca5 100644
--- a/framework/util/fn_padString.sqf
+++ b/framework/util/functions/fn_padString.sqf
@@ -1,3 +1,5 @@
+#include "..\script_component.hpp"
+
params [
["_text", "", [""]],
["_padSide", "left", ["left", "right"]],
diff --git a/framework/util/fn_recurseSubclasses.sqf b/framework/util/functions/fn_recurseSubclasses.sqf
similarity index 93%
rename from framework/util/fn_recurseSubclasses.sqf
rename to framework/util/functions/fn_recurseSubclasses.sqf
index b4ba431..73cf984 100644
--- a/framework/util/fn_recurseSubclasses.sqf
+++ b/framework/util/functions/fn_recurseSubclasses.sqf
@@ -1,3 +1,5 @@
+#include "..\script_component.hpp"
+
params [
["_cfg", configNull, [configNull]],
["_code", {}, [{}]]
diff --git a/framework/util/script_component.hpp b/framework/util/script_component.hpp
new file mode 100644
index 0000000..36f9a27
--- /dev/null
+++ b/framework/util/script_component.hpp
@@ -0,0 +1,3 @@
+#define COMPONENT util
+#define COMPONENT_BEAUTIFIED Utilities
+#include "../script_mod.hpp"
\ No newline at end of file
diff --git a/framework/x/cba/addons/main/script_macros_common.hpp b/framework/x/cba/addons/main/script_macros_common.hpp
new file mode 100644
index 0000000..c2e5d56
--- /dev/null
+++ b/framework/x/cba/addons/main/script_macros_common.hpp
@@ -0,0 +1,1835 @@
+/*
+ Header: script_macros_common.hpp
+
+ Description:
+ A general set of useful macro functions for use by CBA itself or by any module that uses CBA.
+
+ Authors:
+ Sickboy and Spooner
+*/
+
+/* ****************************************************
+ New - Should be exported to general addon
+ Aim:
+ - Simplify (shorten) the amount of characters required for repetitive tasks
+ - Provide a solid structure that can be dynamic and easy editable (Which sometimes means we cannot adhere to Aim #1 ;-)
+ An example is the path that is built from defines. Some available in this file, others in mods and addons.
+
+ Follows Standard:
+ Object variables: PREFIX_COMPONENT
+ Main-object variables: PREFIX_main
+ Paths: MAINPREFIX\PREFIX\SUBPREFIX\COMPONENT\SCRIPTNAME.sqf
+ e.g: x\six\addons\sys_menu\fDate.sqf
+
+ Usage:
+ define PREFIX and COMPONENT, then include this file
+ (Note, you could have a main addon for your mod, define the PREFIX in a macros.hpp,
+ and include this script_macros_common.hpp file.
+ Then in your addons, add a component.hpp, define the COMPONENT,
+ and include your mod's script_macros.hpp
+ In your scripts you can then include the addon's component.hpp with relative path)
+
+ use in subcomponents (subconfigs)
+ define SUBCOMPONENT and include parent component's script_component.hpp
+ currently only supported by SUBADDON, additional macros may be added in the future
+
+ TODO:
+ - Try only to use 1 string type " vs '
+ - Evaluate double functions, and simplification
+ - Evaluate naming scheme; current = prototype
+ - Evaluate "Debug" features..
+ - Evaluate "create mini function per precompiled script, that will load the script on first usage, rather than on init"
+ - Also saw "Namespace" typeName, evaluate which we need :P
+ - Single/Multi player gamelogics? (Incase of MP, you would want only 1 gamelogic per component, which is pv'ed from server, etc)
+ */
+
+#ifndef MAINPREFIX
+ #define MAINPREFIX x
+#endif
+
+#ifndef SUBPREFIX
+ #define SUBPREFIX addons
+#endif
+
+#ifndef MAINLOGIC
+ #define MAINLOGIC main
+#endif
+
+#define ADDON DOUBLES(PREFIX,COMPONENT)
+#define MAIN_ADDON DOUBLES(PREFIX,main)
+
+#ifdef SUBCOMPONENT
+ #define SUBADDON DOUBLES(ADDON,SUBCOMPONENT)
+#endif
+
+/* -------------------------------------------
+Macro: VERSION_CONFIG
+ Define CBA Versioning System config entries.
+
+ VERSION should be a floating-point number (1 separator).
+ VERSION_STR is a string representation of the version.
+ VERSION_AR is an array representation of the version.
+
+ VERSION must always be defined, otherwise it is 0.
+ VERSION_STR and VERSION_AR default to VERSION if undefined.
+
+Parameters:
+ None
+
+Example:
+ (begin example)
+ #define VERSION 1.0
+ #define VERSION_STR 1.0.1
+ #define VERSION_AR 1,0,1
+
+ class CfgPatches {
+ class MyMod_main {
+ VERSION_CONFIG;
+ };
+ };
+ (end)
+
+Author:
+ ?, Jonpas
+------------------------------------------- */
+#ifndef VERSION
+ #define VERSION 0
+#endif
+
+#ifndef VERSION_STR
+ #define VERSION_STR VERSION
+#endif
+
+#ifndef VERSION_AR
+ #define VERSION_AR VERSION
+#endif
+
+#ifndef VERSION_CONFIG
+ #define VERSION_CONFIG version = VERSION; versionStr = QUOTE(VERSION_STR); versionAr[] = {VERSION_AR}
+#endif
+
+/* -------------------------------------------
+Group: Debugging
+------------------------------------------- */
+
+/* -------------------------------------------
+Macros: DEBUG_MODE_x
+ Managing debugging based on debug level.
+
+ According to the *highest* level of debugging that has been defined *before* script_macros_common.hpp is included,
+ only the appropriate debugging commands will be functional. With no level explicitely defined, assume DEBUG_MODE_NORMAL.
+
+ DEBUG_MODE_FULL - Full debugging output.
+ DEBUG_MODE_NORMAL - All debugging except and (Default setting if none specified).
+ DEBUG_MODE_MINIMAL - Only and enabled.
+
+Examples:
+ In order to turn on full debugging for a single file,
+ (begin example)
+ // Top of individual script file.
+ #define DEBUG_MODE_FULL
+
+ (end)
+
+ In order to force minimal debugging for a single component,
+ (begin example)
+ // Top of addons\\script_component.hpp
+ // Ensure that any FULL and NORMAL setting from the individual files are undefined and MINIMAL is set.
+ #ifdef DEBUG_MODE_FULL
+ #undef DEBUG_MODE_FULL
+ #endif
+ #ifdef DEBUG_MODE_NORMAL
+ #undef DEBUG_MODE_NORMAL
+ #endif
+ #ifndef DEBUG_MODE_MINIMAL
+ #define DEBUG_MODE_MINIMAL
+ #endif
+
+ (end)
+
+ In order to turn on full debugging for a whole addon,
+ (begin example)
+ // Top of addons\main\script_macros.hpp
+ #ifndef DEBUG_MODE_FULL
+ #define DEBUG_MODE_FULL
+ #endif
+
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+
+// If DEBUG_MODE_FULL, then also enable DEBUG_MODE_NORMAL.
+#ifdef DEBUG_MODE_FULL
+#define DEBUG_MODE_NORMAL
+#endif
+
+// If DEBUG_MODE_NORMAL, then also enable DEBUG_MODE_MINIMAL.
+#ifdef DEBUG_MODE_NORMAL
+#define DEBUG_MODE_MINIMAL
+#endif
+
+// If no debug modes specified, use DEBUG_MODE_NORMAL (+ DEBUG_MODE_MINIMAL).
+#ifndef DEBUG_MODE_MINIMAL
+#define DEBUG_MODE_NORMAL
+#define DEBUG_MODE_MINIMAL
+#endif
+
+#define LOG_SYS_FORMAT(LEVEL,MESSAGE) format ['[%1] (%2) %3: %4', toUpper 'PREFIX', 'COMPONENT', LEVEL, MESSAGE]
+
+#ifdef DEBUG_SYNCHRONOUS
+#define LOG_SYS(LEVEL,MESSAGE) diag_log text LOG_SYS_FORMAT(LEVEL,MESSAGE)
+#else
+#define LOG_SYS(LEVEL,MESSAGE) LOG_SYS_FORMAT(LEVEL,MESSAGE) call CBA_fnc_log
+#endif
+
+#define LOG_SYS_FILELINENUMBERS(LEVEL,MESSAGE) LOG_SYS(LEVEL,format [ARR_4('%1 %2:%3',MESSAGE,__FILE__,__LINE__ + 1)])
+
+/* -------------------------------------------
+Macro: LOG()
+ Log a debug message into the RPT log.
+
+ Only run if is defined.
+
+Parameters:
+ MESSAGE - Message to record
+
+Example:
+ (begin example)
+ LOG("Initiated clog-dancing simulator.");
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#ifdef DEBUG_MODE_FULL
+
+#define LOG(MESSAGE) LOG_SYS('LOG',MESSAGE)
+#define LOG_1(MESSAGE,ARG1) LOG(FORMAT_1(MESSAGE,ARG1))
+#define LOG_2(MESSAGE,ARG1,ARG2) LOG(FORMAT_2(MESSAGE,ARG1,ARG2))
+#define LOG_3(MESSAGE,ARG1,ARG2,ARG3) LOG(FORMAT_3(MESSAGE,ARG1,ARG2,ARG3))
+#define LOG_4(MESSAGE,ARG1,ARG2,ARG3,ARG4) LOG(FORMAT_4(MESSAGE,ARG1,ARG2,ARG3,ARG4))
+#define LOG_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5) LOG(FORMAT_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5))
+#define LOG_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) LOG(FORMAT_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6))
+#define LOG_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) LOG(FORMAT_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7))
+#define LOG_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) LOG(FORMAT_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8))
+
+#else
+
+#define LOG(MESSAGE) /* disabled */
+#define LOG_1(MESSAGE,ARG1) /* disabled */
+#define LOG_2(MESSAGE,ARG1,ARG2) /* disabled */
+#define LOG_3(MESSAGE,ARG1,ARG2,ARG3) /* disabled */
+#define LOG_4(MESSAGE,ARG1,ARG2,ARG3,ARG4) /* disabled */
+#define LOG_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5) /* disabled */
+#define LOG_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) /* disabled */
+#define LOG_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) /* disabled */
+#define LOG_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) /* disabled */
+
+#endif
+
+/* -------------------------------------------
+Macro: INFO()
+ Record a message without file and line number in the RPT log.
+
+Parameters:
+ MESSAGE - Message to record
+
+Example:
+ (begin example)
+ INFO("Mod X is loaded, do Y");
+ (end)
+
+Author:
+ commy2
+------------------------------------------- */
+#define INFO(MESSAGE) LOG_SYS('INFO',MESSAGE)
+#define INFO_1(MESSAGE,ARG1) INFO(FORMAT_1(MESSAGE,ARG1))
+#define INFO_2(MESSAGE,ARG1,ARG2) INFO(FORMAT_2(MESSAGE,ARG1,ARG2))
+#define INFO_3(MESSAGE,ARG1,ARG2,ARG3) INFO(FORMAT_3(MESSAGE,ARG1,ARG2,ARG3))
+#define INFO_4(MESSAGE,ARG1,ARG2,ARG3,ARG4) INFO(FORMAT_4(MESSAGE,ARG1,ARG2,ARG3,ARG4))
+#define INFO_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5) INFO(FORMAT_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5))
+#define INFO_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) INFO(FORMAT_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6))
+#define INFO_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) INFO(FORMAT_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7))
+#define INFO_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) INFO(FORMAT_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8))
+
+/* -------------------------------------------
+Macro: WARNING()
+ Record a non-critical error in the RPT log.
+
+ Only run if or higher is defined.
+
+Parameters:
+ MESSAGE - Message to record
+
+Example:
+ (begin example)
+ WARNING("This function has been deprecated. Please don't use it in future!");
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#ifdef DEBUG_MODE_NORMAL
+
+#define WARNING(MESSAGE) LOG_SYS('WARNING',MESSAGE)
+#define WARNING_1(MESSAGE,ARG1) WARNING(FORMAT_1(MESSAGE,ARG1))
+#define WARNING_2(MESSAGE,ARG1,ARG2) WARNING(FORMAT_2(MESSAGE,ARG1,ARG2))
+#define WARNING_3(MESSAGE,ARG1,ARG2,ARG3) WARNING(FORMAT_3(MESSAGE,ARG1,ARG2,ARG3))
+#define WARNING_4(MESSAGE,ARG1,ARG2,ARG3,ARG4) WARNING(FORMAT_4(MESSAGE,ARG1,ARG2,ARG3,ARG4))
+#define WARNING_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5) WARNING(FORMAT_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5))
+#define WARNING_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) WARNING(FORMAT_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6))
+#define WARNING_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) WARNING(FORMAT_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7))
+#define WARNING_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) WARNING(FORMAT_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8))
+
+#else
+
+#define WARNING(MESSAGE) /* disabled */
+#define WARNING_1(MESSAGE,ARG1) /* disabled */
+#define WARNING_2(MESSAGE,ARG1,ARG2) /* disabled */
+#define WARNING_3(MESSAGE,ARG1,ARG2,ARG3) /* disabled */
+#define WARNING_4(MESSAGE,ARG1,ARG2,ARG3,ARG4) /* disabled */
+#define WARNING_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5) /* disabled */
+#define WARNING_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) /* disabled */
+#define WARNING_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) /* disabled */
+#define WARNING_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) /* disabled */
+
+#endif
+
+/* -------------------------------------------
+Macro: ERROR()
+ Record a critical error in the RPT log.
+
+Parameters:
+ MESSAGE - Message to record
+
+Example:
+ (begin example)
+ ERROR("value of frog not found in config ...yada...yada...");
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define ERROR(MESSAGE) LOG_SYS('ERROR',MESSAGE)
+#define ERROR_1(MESSAGE,ARG1) ERROR(FORMAT_1(MESSAGE,ARG1))
+#define ERROR_2(MESSAGE,ARG1,ARG2) ERROR(FORMAT_2(MESSAGE,ARG1,ARG2))
+#define ERROR_3(MESSAGE,ARG1,ARG2,ARG3) ERROR(FORMAT_3(MESSAGE,ARG1,ARG2,ARG3))
+#define ERROR_4(MESSAGE,ARG1,ARG2,ARG3,ARG4) ERROR(FORMAT_4(MESSAGE,ARG1,ARG2,ARG3,ARG4))
+#define ERROR_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5) ERROR(FORMAT_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5))
+#define ERROR_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) ERROR(FORMAT_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6))
+#define ERROR_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) ERROR(FORMAT_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7))
+#define ERROR_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) ERROR(FORMAT_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8))
+
+/* -------------------------------------------
+Macro: ERROR_MSG()
+ Record a critical error in the RPT log and display on screen error message.
+
+ Newlines (\n) in the MESSAGE will be put on separate lines.
+
+Parameters:
+ MESSAGE - Message to record
+
+Example:
+ (begin example)
+ ERROR_MSG("value of frog not found in config ...yada...yada...");
+ (end)
+
+Author:
+ commy2
+------------------------------------------- */
+#define ERROR_MSG(MESSAGE) ['PREFIX', 'COMPONENT', nil, MESSAGE, __FILE__, __LINE__ + 1] call CBA_fnc_error
+#define ERROR_MSG_1(MESSAGE,ARG1) ERROR_MSG(FORMAT_1(MESSAGE,ARG1))
+#define ERROR_MSG_2(MESSAGE,ARG1,ARG2) ERROR_MSG(FORMAT_2(MESSAGE,ARG1,ARG2))
+#define ERROR_MSG_3(MESSAGE,ARG1,ARG2,ARG3) ERROR_MSG(FORMAT_3(MESSAGE,ARG1,ARG2,ARG3))
+#define ERROR_MSG_4(MESSAGE,ARG1,ARG2,ARG3,ARG4) ERROR_MSG(FORMAT_4(MESSAGE,ARG1,ARG2,ARG3,ARG4))
+#define ERROR_MSG_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5) ERROR_MSG(FORMAT_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5))
+#define ERROR_MSG_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) ERROR_MSG(FORMAT_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6))
+#define ERROR_MSG_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) ERROR_MSG(FORMAT_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7))
+#define ERROR_MSG_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) ERROR_MSG(FORMAT_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8))
+
+/* -------------------------------------------
+Macro: ERROR_WITH_TITLE()
+ Record a critical error in the RPT log.
+
+ The title can be specified (in the heading is always just "ERROR")
+ Newlines (\n) in the MESSAGE will be put on separate lines.
+
+Parameters:
+ TITLE - Title of error message
+ MESSAGE - Body of error message
+
+Example:
+ (begin example)
+ ERROR_WITH_TITLE("Value not found","Value of frog not found in config ...yada...yada...");
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define ERROR_WITH_TITLE(TITLE,MESSAGE) ['PREFIX', 'COMPONENT', TITLE, MESSAGE, __FILE__, __LINE__ + 1] call CBA_fnc_error
+#define ERROR_WITH_TITLE_1(TITLE,MESSAGE,ARG1) ERROR_WITH_TITLE(TITLE,FORMAT_1(MESSAGE,ARG1))
+#define ERROR_WITH_TITLE_2(TITLE,MESSAGE,ARG1,ARG2) ERROR_WITH_TITLE(TITLE,FORMAT_2(MESSAGE,ARG1,ARG2))
+#define ERROR_WITH_TITLE_3(TITLE,MESSAGE,ARG1,ARG2,ARG3) ERROR_WITH_TITLE(TITLE,FORMAT_3(MESSAGE,ARG1,ARG2,ARG3))
+#define ERROR_WITH_TITLE_4(TITLE,MESSAGE,ARG1,ARG2,ARG3,ARG4) ERROR_WITH_TITLE(TITLE,FORMAT_4(MESSAGE,ARG1,ARG2,ARG3,ARG4))
+#define ERROR_WITH_TITLE_5(TITLE,MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5) ERROR_WITH_TITLE(TITLE,FORMAT_5(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5))
+#define ERROR_WITH_TITLE_6(TITLE,MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) ERROR_WITH_TITLE(TITLE,FORMAT_6(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6))
+#define ERROR_WITH_TITLE_7(TITLE,MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) ERROR_WITH_TITLE(TITLE,FORMAT_7(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7))
+#define ERROR_WITH_TITLE_8(TITLE,MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) ERROR_WITH_TITLE(TITLE,FORMAT_8(MESSAGE,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8))
+
+/* -------------------------------------------
+Macro: MESSAGE_WITH_TITLE()
+ Record a single line in the RPT log.
+
+Parameters:
+ TITLE - Title of log message
+ MESSAGE - Body of message
+
+Example:
+ (begin example)
+ MESSAGE_WITH_TITLE("Value found","Value of frog found in config ");
+ (end)
+
+Author:
+ Killswitch
+------------------------------------------- */
+#define MESSAGE_WITH_TITLE(TITLE,MESSAGE) LOG_SYS_FILELINENUMBERS(TITLE,MESSAGE)
+
+/* -------------------------------------------
+Macro: RETDEF()
+ If a variable is undefined, return the default value. Otherwise, return the
+ variable itself.
+
+Parameters:
+ VARIABLE - the variable to check
+ DEFAULT_VALUE - the default value to use if variable is undefined
+
+Example:
+ (begin example)
+ // _var is undefined
+ hintSilent format ["_var=%1", RETDEF(_var,5)]; // "_var=5"
+ _var = 7;
+ hintSilent format ["_var=%1", RETDEF(_var,5)]; // "_var=7"
+ (end example)
+Author:
+ 654wak654
+------------------------------------------- */
+#define RETDEF(VARIABLE,DEFAULT_VALUE) (if (isNil {VARIABLE}) then [{DEFAULT_VALUE}, {VARIABLE}])
+
+/* -------------------------------------------
+Macro: RETNIL()
+ If a variable is undefined, return the value nil. Otherwise, return the
+ variable itself.
+
+Parameters:
+ VARIABLE - the variable to check
+
+Example:
+ (begin example)
+ // _var is undefined
+ hintSilent format ["_var=%1", RETNIL(_var)]; // "_var=any"
+ (end example)
+
+Author:
+ Alef (see CBA issue #8514)
+------------------------------------------- */
+#define RETNIL(VARIABLE) RETDEF(VARIABLE,nil)
+
+/* -------------------------------------------
+Macros: TRACE_n()
+ Log a message and 1-8 variables to the RPT log.
+
+ Only run if is defined.
+
+ TRACE_1(MESSAGE,A) - Log 1 variable.
+ TRACE_2(MESSAGE,A,B) - Log 2 variables.
+ TRACE_3(MESSAGE,A,B,C) - Log 3 variables.
+ TRACE_4(MESSAGE,A,B,C,D) - Log 4 variables.
+ TRACE_5(MESSAGE,A,B,C,D,E) - Log 5 variables.
+ TRACE_6(MESSAGE,A,B,C,D,E,F) - Log 6 variables.
+ TRACE_7(MESSAGE,A,B,C,D,E,F,G) - Log 7 variables.
+ TRACE_8(MESSAGE,A,B,C,D,E,F,G,H) - Log 8 variables.
+ TRACE_9(MESSAGE,A,B,C,D,E,F,G,H,I) - Log 9 variables.
+
+Parameters:
+ MESSAGE - Message to add to the trace [String]
+ A..H - Variable names to log values of [Any]
+
+Example:
+ (begin example)
+ TRACE_3("After takeoff",_vehicle player,getPos (_vehicle player), getPosASL (_vehicle player));
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define PFORMAT_1(MESSAGE,A) \
+ format ['%1: A=%2', MESSAGE, RETNIL(A)]
+
+#define PFORMAT_2(MESSAGE,A,B) \
+ format ['%1: A=%2, B=%3', MESSAGE, RETNIL(A), RETNIL(B)]
+
+#define PFORMAT_3(MESSAGE,A,B,C) \
+ format ['%1: A=%2, B=%3, C=%4', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C)]
+
+#define PFORMAT_4(MESSAGE,A,B,C,D) \
+ format ['%1: A=%2, B=%3, C=%4, D=%5', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C), RETNIL(D)]
+
+#define PFORMAT_5(MESSAGE,A,B,C,D,E) \
+ format ['%1: A=%2, B=%3, C=%4, D=%5, E=%6', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C), RETNIL(D), RETNIL(E)]
+
+#define PFORMAT_6(MESSAGE,A,B,C,D,E,F) \
+ format ['%1: A=%2, B=%3, C=%4, D=%5, E=%6, F=%7', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C), RETNIL(D), RETNIL(E), RETNIL(F)]
+
+#define PFORMAT_7(MESSAGE,A,B,C,D,E,F,G) \
+ format ['%1: A=%2, B=%3, C=%4, D=%5, E=%6, F=%7, G=%8', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C), RETNIL(D), RETNIL(E), RETNIL(F), RETNIL(G)]
+
+#define PFORMAT_8(MESSAGE,A,B,C,D,E,F,G,H) \
+ format ['%1: A=%2, B=%3, C=%4, D=%5, E=%6, F=%7, G=%8, H=%9', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C), RETNIL(D), RETNIL(E), RETNIL(F), RETNIL(G), RETNIL(H)]
+
+#define PFORMAT_9(MESSAGE,A,B,C,D,E,F,G,H,I) \
+ format ['%1: A=%2, B=%3, C=%4, D=%5, E=%6, F=%7, G=%8, H=%9, I=%10', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C), RETNIL(D), RETNIL(E), RETNIL(F), RETNIL(G), RETNIL(H), RETNIL(I)]
+
+
+#ifdef DEBUG_MODE_FULL
+#define TRACE_1(MESSAGE,A) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_1(str diag_frameNo + ' ' + (MESSAGE),A))
+#define TRACE_2(MESSAGE,A,B) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_2(str diag_frameNo + ' ' + (MESSAGE),A,B))
+#define TRACE_3(MESSAGE,A,B,C) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_3(str diag_frameNo + ' ' + (MESSAGE),A,B,C))
+#define TRACE_4(MESSAGE,A,B,C,D) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_4(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D))
+#define TRACE_5(MESSAGE,A,B,C,D,E) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_5(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E))
+#define TRACE_6(MESSAGE,A,B,C,D,E,F) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_6(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F))
+#define TRACE_7(MESSAGE,A,B,C,D,E,F,G) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_7(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F,G))
+#define TRACE_8(MESSAGE,A,B,C,D,E,F,G,H) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_8(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F,G,H))
+#define TRACE_9(MESSAGE,A,B,C,D,E,F,G,H,I) LOG_SYS_FILELINENUMBERS('TRACE',PFORMAT_9(str diag_frameNo + ' ' + (MESSAGE),A,B,C,D,E,F,G,H,I))
+#else
+#define TRACE_1(MESSAGE,A) /* disabled */
+#define TRACE_2(MESSAGE,A,B) /* disabled */
+#define TRACE_3(MESSAGE,A,B,C) /* disabled */
+#define TRACE_4(MESSAGE,A,B,C,D) /* disabled */
+#define TRACE_5(MESSAGE,A,B,C,D,E) /* disabled */
+#define TRACE_6(MESSAGE,A,B,C,D,E,F) /* disabled */
+#define TRACE_7(MESSAGE,A,B,C,D,E,F,G) /* disabled */
+#define TRACE_8(MESSAGE,A,B,C,D,E,F,G,H) /* disabled */
+#define TRACE_9(MESSAGE,A,B,C,D,E,F,G,H,I) /* disabled */
+#endif
+
+/* -------------------------------------------
+Group: General
+------------------------------------------- */
+
+// *************************************
+// Internal Functions
+#define DOUBLES(var1,var2) var1##_##var2
+#define TRIPLES(var1,var2,var3) var1##_##var2##_##var3
+#define QUOTE(var1) #var1
+
+#ifdef MODULAR
+ #define COMPONENT_T DOUBLES(t,COMPONENT)
+ #define COMPONENT_M DOUBLES(m,COMPONENT)
+ #define COMPONENT_S DOUBLES(s,COMPONENT)
+ #define COMPONENT_C DOUBLES(c,COMPONENT)
+ #define COMPONENT_F COMPONENT_C
+#else
+ #define COMPONENT_T COMPONENT
+ #define COMPONENT_M COMPONENT
+ #define COMPONENT_S COMPONENT
+ #define COMPONENT_F COMPONENT
+ #define COMPONENT_C COMPONENT
+#endif
+
+/* -------------------------------------------
+Macro: INC()
+
+Description:
+ Increase a number by one.
+
+Parameters:
+ VAR - Variable to increment [Number]
+
+Example:
+ (begin example)
+ _counter = 0;
+ INC(_counter);
+ // _counter => 1
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define INC(var) var = (var) + 1
+
+/* -------------------------------------------
+Macro: DEC()
+
+Description:
+ Decrease a number by one.
+
+Parameters:
+ VAR - Variable to decrement [Number]
+
+Example:
+ (begin example)
+ _counter = 99;
+ DEC(_counter);
+ // _counter => 98
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define DEC(var) var = (var) - 1
+
+/* -------------------------------------------
+Macro: ADD()
+
+Description:
+ Add a value to a variable. Variable and value should be both Numbers or both Strings.
+
+Parameters:
+ VAR - Variable to add to [Number or String]
+ VALUE - Value to add [Number or String]
+
+Examples:
+ (begin example)
+ _counter = 2;
+ ADD(_counter,3);
+ // _counter => 5
+ (end)
+ (begin example)
+ _str = "hello";
+ ADD(_str," ");
+ ADD(_str,"Fred");
+ // _str => "hello Fred"
+ (end)
+
+Author:
+ Sickboy
+------------------------------------------- */
+#define ADD(var1,var2) var1 = (var1) + (var2)
+
+/* -------------------------------------------
+Macro: SUB()
+
+Description:
+ Subtract a value from a number variable. VAR and VALUE should both be Numbers.
+
+Parameters:
+ VAR - Variable to subtract from [Number]
+ VALUE - Value to subtract [Number]
+
+Examples:
+ (begin example)
+ _numChickens = 2;
+ SUB(_numChickens,3);
+ // _numChickens => -1
+ (end)
+------------------------------------------- */
+#define SUB(var1,var2) var1 = (var1) - (var2)
+
+/* -------------------------------------------
+Macro: REM()
+
+Description:
+ Remove an element from an array each time it occurs.
+
+ This recreates the entire array, so use BIS_fnc_removeIndex if modification of the original array is required
+ or if only one of the elements that matches ELEMENT needs to be removed.
+
+Parameters:
+ ARRAY - Array to modify [Array]
+ ELEMENT - Element to remove [Any]
+
+Examples:
+ (begin example)
+ _array = [1, 2, 3, 4, 3, 8];
+ REM(_array,3);
+ // _array = [1, 2, 4, 8];
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define REM(var1,var2) SUB(var1,[var2])
+
+/* -------------------------------------------
+Macro: PUSH()
+
+Description:
+ Appends a single value onto the end of an ARRAY. Change is made to the ARRAY itself, not creating a new array.
+
+Parameters:
+ ARRAY - Array to push element onto [Array]
+ ELEMENT - Element to push [Any]
+
+Examples:
+ (begin example)
+ _fish = ["blue", "green", "smelly"];
+ PUSH(_fish,"monkey-flavoured");
+ // _fish => ["blue", "green", "smelly", "monkey-flavoured"]
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define PUSH(var1,var2) (var1) pushBack (var2)
+
+/* -------------------------------------------
+Macro: MAP()
+Description:
+ Applies given code to each element of the array, then assigns the
+ resulting array to the original
+Parameters:
+ ARRAY - Array to be modified
+ CODE - Code that'll be applied to each element of the array.
+Example:
+ (begin example)
+ _array = [1, 2, 3, 4, 3, 8];
+ MAP(_array,_x + 1);
+ // _array is now [2, 3, 4, 5, 4, 9];
+ (end)
+Author:
+ 654wak654
+------------------------------------------- */
+#define MAP(ARR,CODE) ARR = ARR apply {CODE}
+
+/* -------------------------------------------
+Macro: FILTER()
+Description:
+ Filters an array based on given code, then assigns the resulting array
+ to the original
+Parameters:
+ ARRAY - Array to be filtered
+ CODE - Condition to pick elements
+Example:
+ (begin example)
+ _array = [1, 2, 3, 4, 3, 8];
+ FILTER(_array,_x % 2 == 0)
+ // _array is now [2, 4, 8];
+ (end)
+Author:
+ Commy2
+------------------------------------------- */
+#define FILTER(ARR,CODE) ARR = ARR select {CODE}
+
+/* -------------------------------------------
+Macro: UNIQUE()
+Description:
+ Removes duplicate values in given array
+Parameters:
+ ARRAY - The array to be modified
+Example:
+ (begin example)
+ _someArray = [4, 4, 5, 5, 5, 2];
+ UNIQUE(_someArray);
+ // _someArray is now [4, 5, 2]
+ (end)
+Author:
+ Commy2
+------------------------------------------- */
+#define UNIQUE(ARR) ARR = ARR arrayIntersect ARR
+
+/* -------------------------------------------
+Macro: INTERSECTION()
+Description:
+ Finds unique common elements between two arrays and assigns them
+ to the first array
+Parameters:
+ ARRAY0 - The array to be modified
+ ARRAY1 - The array to find intersections with
+Example:
+ (begin example)
+ _someArray = [1, 2, 3, 4, 5, 5];
+ _anotherArray = [4, 5, 6, 7];
+ INTERSECTION(_someArray,_anotherArray);
+ // _someArray is now [4, 5]
+ (end)
+Author:
+ 654wak654
+------------------------------------------- */
+#define INTERSECTION(ARG0,ARG1) ARG0 = ARG0 arrayIntersect (ARG1)
+
+/* -------------------------------------------
+Macro: ISNILS()
+
+Description:
+ Sets a variable with a value, but only if it is undefined.
+
+Parameters:
+ VARIABLE - Variable to set [Any, not nil]
+ DEFAULT_VALUE - Value to set VARIABLE to if it is undefined [Any, not nil]
+
+Examples:
+ (begin example)
+ // _fish is undefined
+ ISNILS(_fish,0);
+ // _fish => 0
+ (end)
+ (begin example)
+ _fish = 12;
+ // ...later...
+ ISNILS(_fish,0);
+ // _fish => 12
+ (end)
+
+Author:
+ Sickboy
+------------------------------------------- */
+#define ISNILS(VARIABLE,DEFAULT_VALUE) if (isNil #VARIABLE) then { VARIABLE = DEFAULT_VALUE }
+#define ISNILS2(var1,var2,var3,var4) ISNILS(TRIPLES(var1,var2,var3),var4)
+#define ISNILS3(var1,var2,var3) ISNILS(DOUBLES(var1,var2),var3)
+#define ISNIL(var1,var2) ISNILS2(PREFIX,COMPONENT,var1,var2)
+#define ISNILMAIN(var1,var2) ISNILS3(PREFIX,var1,var2)
+
+#define CREATELOGICS(var1,var2) var1##_##var2 = ([sideLogic] call CBA_fnc_getSharedGroup) createUnit ["LOGIC", [0, 0, 0], [], 0, "NONE"]
+#define CREATELOGICLOCALS(var1,var2) var1##_##var2 = "LOGIC" createVehicleLocal [0, 0, 0]
+#define CREATELOGICGLOBALS(var1,var2) var1##_##var2 = ([sideLogic] call CBA_fnc_getSharedGroup) createUnit ["LOGIC", [0, 0, 0], [], 0, "NONE"]; publicVariable QUOTE(DOUBLES(var1,var2))
+#define CREATELOGICGLOBALTESTS(var1,var2) var1##_##var2 = ([sideLogic] call CBA_fnc_getSharedGroup) createUnit [QUOTE(DOUBLES(ADDON,logic)), [0, 0, 0], [], 0, "NONE"]
+
+#define GETVARS(var1,var2,var3) (var1##_##var2 getVariable #var3)
+#define GETVARMAINS(var1,var2) GETVARS(var1,MAINLOGIC,var2)
+
+#ifndef PATHTO_SYS
+ #define PATHTO_SYS(var1,var2,var3) \MAINPREFIX\var1\SUBPREFIX\var2\var3.sqf
+#endif
+#ifndef PATHTOF_SYS
+ #define PATHTOF_SYS(var1,var2,var3) \MAINPREFIX\var1\SUBPREFIX\var2\var3
+#endif
+
+#ifndef PATHTOF2_SYS
+ #define PATHTOF2_SYS(var1,var2,var3) MAINPREFIX\var1\SUBPREFIX\var2\var3
+#endif
+
+#define PATHTO_R(var1) PATHTOF2_SYS(PREFIX,COMPONENT_C,var1)
+#define PATHTO_T(var1) PATHTOF_SYS(PREFIX,COMPONENT_T,var1)
+#define PATHTO_M(var1) PATHTOF_SYS(PREFIX,COMPONENT_M,var1)
+#define PATHTO_S(var1) PATHTOF_SYS(PREFIX,COMPONENT_S,var1)
+#define PATHTO_C(var1) PATHTOF_SYS(PREFIX,COMPONENT_C,var1)
+#define PATHTO_F(var1) PATHTO_SYS(PREFIX,COMPONENT_F,var1)
+
+// Already quoted ""
+#define QPATHTO_R(var1) QUOTE(PATHTO_R(var1))
+#define QPATHTO_T(var1) QUOTE(PATHTO_T(var1))
+#define QPATHTO_M(var1) QUOTE(PATHTO_M(var1))
+#define QPATHTO_S(var1) QUOTE(PATHTO_S(var1))
+#define QPATHTO_C(var1) QUOTE(PATHTO_C(var1))
+#define QPATHTO_F(var1) QUOTE(PATHTO_F(var1))
+
+// This only works for binarized configs after recompiling the pbos
+// TODO: Reduce amount of calls / code..
+#define COMPILE_FILE2_CFG_SYS(var1) compile preprocessFileLineNumbers var1
+#define COMPILE_FILE2_SYS(var1) COMPILE_FILE2_CFG_SYS(var1)
+
+#define COMPILE_FILE_SYS(var1,var2,var3) COMPILE_FILE2_SYS('PATHTO_SYS(var1,var2,var3)')
+#define COMPILE_FILE_CFG_SYS(var1,var2,var3) COMPILE_FILE2_CFG_SYS('PATHTO_SYS(var1,var2,var3)')
+
+#define SETVARS(var1,var2) var1##_##var2 setVariable
+#define SETVARMAINS(var1) SETVARS(var1,MAINLOGIC)
+#define GVARMAINS(var1,var2) var1##_##var2
+#define CFGSETTINGSS(var1,var2) configFile >> "CfgSettings" >> #var1 >> #var2
+//#define SETGVARS(var1,var2,var3) var1##_##var2##_##var3 =
+//#define SETGVARMAINS(var1,var2) var1##_##var2 =
+
+// Compile-Once, JIT: On first use.
+// #define PREPMAIN_SYS(var1,var2,var3) var1##_fnc_##var3 = { var1##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3)); if (isNil "_this") then { call var1##_fnc_##var3 } else { _this call var1##_fnc_##var3 } }
+// #define PREP_SYS(var1,var2,var3) var1##_##var2##_fnc_##var3 = { var1##_##var2##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3)); if (isNil "_this") then { call var1##_##var2##_fnc_##var3 } else { _this call var1##_##var2##_fnc_##var3 } }
+// #define PREP_SYS2(var1,var2,var3,var4) var1##_##var2##_fnc_##var4 = { var1##_##var2##_fnc_##var4 = COMPILE_FILE_SYS(var1,var3,DOUBLES(fnc,var4)); if (isNil "_this") then { call var1##_##var2##_fnc_##var4 } else { _this call var1##_##var2##_fnc_##var4 } }
+
+// Compile-Once, at Macro. As opposed to Compile-Once, on first use.
+#define PREPMAIN_SYS(var1,var2,var3) var1##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3))
+#define PREP_SYS(var1,var2,var3) var1##_##var2##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3))
+#define PREP_SYS2(var1,var2,var3,var4) var1##_##var2##_fnc_##var4 = COMPILE_FILE_SYS(var1,var3,DOUBLES(fnc,var4))
+
+#define LSTR(var1) TRIPLES(ADDON,STR,var1)
+
+#ifndef DEBUG_SETTINGS
+ #define DEBUG_SETTINGS [false, true, false]
+#endif
+
+#define MSG_INIT QUOTE(Initializing: ADDON version: VERSION)
+
+// *************************************
+// User Functions
+#define CFGSETTINGS CFGSETTINGSS(PREFIX,COMPONENT)
+#define PATHTO(var1) PATHTO_SYS(PREFIX,COMPONENT_F,var1)
+#define PATHTOF(var1) PATHTOF_SYS(PREFIX,COMPONENT,var1)
+#define PATHTOEF(var1,var2) PATHTOF_SYS(PREFIX,var1,var2)
+#define QPATHTOF(var1) QUOTE(PATHTOF(var1))
+#define QPATHTOEF(var1,var2) QUOTE(PATHTOEF(var1,var2))
+
+#define COMPILE_FILE(var1) COMPILE_FILE_SYS(PREFIX,COMPONENT_F,var1)
+#define COMPILE_FILE_CFG(var1) COMPILE_FILE_CFG_SYS(PREFIX,COMPONENT_F,var1)
+#define COMPILE_FILE2(var1) COMPILE_FILE2_SYS('var1')
+#define COMPILE_FILE2_CFG(var1) COMPILE_FILE2_CFG_SYS('var1')
+
+#define COMPILE_SCRIPT(var1) compileScript ['PATHTO_SYS(PREFIX,COMPONENT_F,var1)']
+
+
+#define VERSIONING_SYS(var1) class CfgSettings { \
+ class CBA { \
+ class Versioning { \
+ class var1 {}; \
+ }; \
+ }; \
+};
+
+#define VERSIONING VERSIONING_SYS(PREFIX)
+
+/* -------------------------------------------
+Macro: GVAR()
+ Get full variable identifier for a global variable owned by this component.
+
+Parameters:
+ VARIABLE - Partial name of global variable owned by this component [Any].
+
+Example:
+ (begin example)
+ GVAR(frog) = 12;
+ // In SPON_FrogDancing component, equivalent to SPON_FrogDancing_frog = 12
+ (end)
+
+Author:
+ Sickboy
+------------------------------------------- */
+#define GVAR(var1) DOUBLES(ADDON,var1)
+#define EGVAR(var1,var2) TRIPLES(PREFIX,var1,var2)
+#define QGVAR(var1) QUOTE(GVAR(var1))
+#define QEGVAR(var1,var2) QUOTE(EGVAR(var1,var2))
+#define QQGVAR(var1) QUOTE(QGVAR(var1))
+#define QQEGVAR(var1,var2) QUOTE(QEGVAR(var1,var2))
+
+/* -------------------------------------------
+Macro: GVARMAIN()
+ Get full variable identifier for a global variable owned by this addon.
+
+Parameters:
+ VARIABLE - Partial name of global variable owned by this addon [Any].
+
+Example:
+ (begin example)
+ GVARMAIN(frog) = 12;
+ // In SPON_FrogDancing component, equivalent to SPON_frog = 12
+ (end)
+
+Author:
+ Sickboy
+------------------------------------------- */
+#define GVARMAIN(var1) GVARMAINS(PREFIX,var1)
+#define QGVARMAIN(var1) QUOTE(GVARMAIN(var1))
+#define QQGVARMAIN(var1) QUOTE(QGVARMAIN(var1))
+// TODO: What's this?
+#define SETTINGS DOUBLES(PREFIX,settings)
+#define CREATELOGIC CREATELOGICS(PREFIX,COMPONENT)
+#define CREATELOGICGLOBAL CREATELOGICGLOBALS(PREFIX,COMPONENT)
+#define CREATELOGICGLOBALTEST CREATELOGICGLOBALTESTS(PREFIX,COMPONENT)
+#define CREATELOGICLOCAL CREATELOGICLOCALS(PREFIX,COMPONENT)
+#define CREATELOGICMAIN CREATELOGICS(PREFIX,MAINLOGIC)
+#define GETVAR(var1) GETVARS(PREFIX,COMPONENT,var1)
+#define SETVAR SETVARS(PREFIX,COMPONENT)
+#define SETVARMAIN SETVARMAINS(PREFIX)
+#define IFCOUNT(var1,var2,var3) if (count var1 > var2) then { var3 = var1 select var2 };
+
+/* -------------------------------------------
+Macro: PREP()
+
+Description:
+ Defines a function.
+
+ Full file path:
+ '\MAINPREFIX\PREFIX\SUBPREFIX\COMPONENT\fnc_.sqf'
+
+ Resulting function name:
+ 'PREFIX_COMPONENT_'
+
+ The PREP macro should be placed in a script run by a XEH preStart and XEH preInit event.
+
+ The PREP macro allows for CBA function caching, which drastically speeds up load times.
+ Beware though that function caching is enabled by default and as such to disable it, you need to
+ #define DISABLE_COMPILE_CACHE above your #include "script_components.hpp" include!
+
+ The function will be defined in ui and mission namespace. It can not be overwritten without
+ a mission restart.
+
+Parameters:
+ FUNCTION NAME - Name of the function, unquoted
+
+Examples:
+ (begin example)
+ PREP(banana);
+ call FUNC(banana);
+ (end)
+
+Author:
+ dixon13
+ ------------------------------------------- */
+//#define PREP(var1) PREP_SYS(PREFIX,COMPONENT_F,var1)
+
+#ifdef DISABLE_COMPILE_CACHE
+ #define PREP(var1) TRIPLES(ADDON,fnc,var1) = compile preProcessFileLineNumbers 'PATHTO_SYS(PREFIX,COMPONENT_F,DOUBLES(fnc,var1))'
+ #define PREPMAIN(var1) TRIPLES(PREFIX,fnc,var1) = compile preProcessFileLineNumbers 'PATHTO_SYS(PREFIX,COMPONENT_F,DOUBLES(fnc,var1))'
+#else
+ #define PREP(var1) ['PATHTO_SYS(PREFIX,COMPONENT_F,DOUBLES(fnc,var1))', 'TRIPLES(ADDON,fnc,var1)'] call SLX_XEH_COMPILE_NEW
+ #define PREPMAIN(var1) ['PATHTO_SYS(PREFIX,COMPONENT_F,DOUBLES(fnc,var1))', 'TRIPLES(PREFIX,fnc,var1)'] call SLX_XEH_COMPILE_NEW
+#endif
+
+/* -------------------------------------------
+Macro: PATHTO_FNC()
+
+Description:
+ Defines a function inside CfgFunctions.
+
+ Full file path in addons:
+ '\MAINPREFIX\PREFIX\SUBPREFIX\COMPONENT\fnc_.sqf'
+ Define 'RECOMPILE' to enable recompiling.
+ Define 'SKIP_FUNCTION_HEADER' to skip adding function header.
+
+Parameters:
+ FUNCTION NAME - Name of the function, unquoted
+
+Examples:
+ (begin example)
+ // file name: fnc_addPerFrameHandler.sqf
+ class CfgFunctions {
+ class CBA {
+ class Misc {
+ PATHTO_FNC(addPerFrameHandler);
+ };
+ };
+ };
+ // -> CBA_fnc_addPerFrameHandler
+ (end)
+
+Author:
+ dixon13, commy2
+ ------------------------------------------- */
+#ifdef RECOMPILE
+ #undef RECOMPILE
+ #define RECOMPILE recompile = 1
+#else
+ #define RECOMPILE recompile = 0
+#endif
+// Set function header type: -1 - no header; 0 - default header; 1 - system header.
+#ifdef SKIP_FUNCTION_HEADER
+ #define CFGFUNCTION_HEADER headerType = -1
+#else
+ #define CFGFUNCTION_HEADER headerType = 0
+#endif
+
+#define PATHTO_FNC(func) class func {\
+ file = QPATHTOF(DOUBLES(fnc,func).sqf);\
+ CFGFUNCTION_HEADER;\
+ RECOMPILE;\
+}
+
+#define FUNC(var1) TRIPLES(ADDON,fnc,var1)
+#define FUNCMAIN(var1) TRIPLES(PREFIX,fnc,var1)
+#define FUNC_INNER(var1,var2) TRIPLES(DOUBLES(PREFIX,var1),fnc,var2)
+#define EFUNC(var1,var2) FUNC_INNER(var1,var2)
+#define QFUNC(var1) QUOTE(FUNC(var1))
+#define QFUNCMAIN(var1) QUOTE(FUNCMAIN(var1))
+#define QFUNC_INNER(var1,var2) QUOTE(FUNC_INNER(var1,var2))
+#define QEFUNC(var1,var2) QUOTE(EFUNC(var1,var2))
+#define QQFUNC(var1) QUOTE(QFUNC(var1))
+#define QQFUNCMAIN(var1) QUOTE(QFUNCMAIN(var1))
+#define QQFUNC_INNER(var1,var2) QUOTE(QFUNC_INNER(var1,var2))
+#define QQEFUNC(var1,var2) QUOTE(QEFUNC(var1,var2))
+
+#ifndef PRELOAD_ADDONS
+ #define PRELOAD_ADDONS class CfgAddons { \
+ class PreloadAddons { \
+ class ADDON { \
+ list[]={ QUOTE(ADDON) }; \
+ }; \
+ }; \
+}
+#endif
+
+/* -------------------------------------------
+Macros: ARG_#()
+ Select from list of array arguments
+
+Parameters:
+ VARIABLE(1-8) - elements for the list
+
+Author:
+ Rommel
+------------------------------------------- */
+#define ARG_1(A,B) ((A) select (B))
+#define ARG_2(A,B,C) (ARG_1(ARG_1(A,B),C))
+#define ARG_3(A,B,C,D) (ARG_1(ARG_2(A,B,C),D))
+#define ARG_4(A,B,C,D,E) (ARG_1(ARG_3(A,B,C,D),E))
+#define ARG_5(A,B,C,D,E,F) (ARG_1(ARG_4(A,B,C,D,E),F))
+#define ARG_6(A,B,C,D,E,F,G) (ARG_1(ARG_5(A,B,C,D,E,F),G))
+#define ARG_7(A,B,C,D,E,F,G,H) (ARG_1(ARG_6(A,B,C,D,E,E,F,G),H))
+#define ARG_8(A,B,C,D,E,F,G,H,I) (ARG_1(ARG_7(A,B,C,D,E,E,F,G,H),I))
+
+/* -------------------------------------------
+Macros: ARR_#()
+ Create list from arguments. Useful for working around , in macro parameters.
+ 1-8 arguments possible.
+
+Parameters:
+ VARIABLE(1-8) - elements for the list
+
+Author:
+ Nou
+------------------------------------------- */
+#define ARR_1(ARG1) ARG1
+#define ARR_2(ARG1,ARG2) ARG1, ARG2
+#define ARR_3(ARG1,ARG2,ARG3) ARG1, ARG2, ARG3
+#define ARR_4(ARG1,ARG2,ARG3,ARG4) ARG1, ARG2, ARG3, ARG4
+#define ARR_5(ARG1,ARG2,ARG3,ARG4,ARG5) ARG1, ARG2, ARG3, ARG4, ARG5
+#define ARR_6(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) ARG1, ARG2, ARG3, ARG4, ARG5, ARG6
+#define ARR_7(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7
+#define ARR_8(ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8
+
+/* -------------------------------------------
+Macros: FORMAT_#(STR, ARG1)
+ Format - Useful for working around , in macro parameters.
+ 1-8 arguments possible.
+
+Parameters:
+ STRING - string used by format
+ VARIABLE(1-8) - elements for usage in format
+
+Author:
+ Nou & Sickboy
+------------------------------------------- */
+#define FORMAT_1(STR,ARG1) format[STR, ARG1]
+#define FORMAT_2(STR,ARG1,ARG2) format[STR, ARG1, ARG2]
+#define FORMAT_3(STR,ARG1,ARG2,ARG3) format[STR, ARG1, ARG2, ARG3]
+#define FORMAT_4(STR,ARG1,ARG2,ARG3,ARG4) format[STR, ARG1, ARG2, ARG3, ARG4]
+#define FORMAT_5(STR,ARG1,ARG2,ARG3,ARG4,ARG5) format[STR, ARG1, ARG2, ARG3, ARG4, ARG5]
+#define FORMAT_6(STR,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6) format[STR, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6]
+#define FORMAT_7(STR,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7) format[STR, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7]
+#define FORMAT_8(STR,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8) format[STR, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8]
+
+// CONTROL(46) 12
+#define DISPLAY(A) (findDisplay A)
+#define CONTROL(A) DISPLAY(A) displayCtrl
+
+/* -------------------------------------------
+Macros: IS_x()
+ Checking the data types of variables.
+
+ IS_ARRAY() - Array
+ IS_BOOL() - Boolean
+ IS_BOOLEAN() - UI display handle(synonym for )
+ IS_CODE() - Code block (i.e a compiled function)
+ IS_CONFIG() - Configuration
+ IS_CONTROL() - UI control handle.
+ IS_DISPLAY() - UI display handle.
+ IS_FUNCTION() - A compiled function (synonym for )
+ IS_GROUP() - Group.
+ IS_INTEGER() - Is a number a whole number?
+ IS_LOCATION() - World location.
+ IS_NUMBER() - A floating point number (synonym for )
+ IS_OBJECT() - World object.
+ IS_SCALAR() - Floating point number.
+ IS_SCRIPT() - A script handle (as returned by execVM and spawn commands).
+ IS_SIDE() - Game side.
+ IS_STRING() - World object.
+ IS_TEXT() - Structured text.
+
+Parameters:
+ VARIABLE - Variable to check if it is of a particular type [Any, not nil]
+
+Author:
+ Spooner
+------------------------------------------- */
+#define IS_META_SYS(VAR,TYPE) (if (isNil {VAR}) then {false} else {(VAR) isEqualType TYPE})
+#define IS_ARRAY(VAR) IS_META_SYS(VAR,[])
+#define IS_BOOL(VAR) IS_META_SYS(VAR,false)
+#define IS_CODE(VAR) IS_META_SYS(VAR,{})
+#define IS_CONFIG(VAR) IS_META_SYS(VAR,configNull)
+#define IS_CONTROL(VAR) IS_META_SYS(VAR,controlNull)
+#define IS_DISPLAY(VAR) IS_META_SYS(VAR,displayNull)
+#define IS_GROUP(VAR) IS_META_SYS(VAR,grpNull)
+#define IS_OBJECT(VAR) IS_META_SYS(VAR,objNull)
+#define IS_SCALAR(VAR) IS_META_SYS(VAR,0)
+#define IS_SCRIPT(VAR) IS_META_SYS(VAR,scriptNull)
+#define IS_SIDE(VAR) IS_META_SYS(VAR,west)
+#define IS_STRING(VAR) IS_META_SYS(VAR,"STRING")
+#define IS_TEXT(VAR) IS_META_SYS(VAR,text "")
+#define IS_LOCATION(VAR) IS_META_SYS(VAR,locationNull)
+
+#define IS_BOOLEAN(VAR) IS_BOOL(VAR)
+#define IS_FUNCTION(VAR) IS_CODE(VAR)
+#define IS_INTEGER(VAR) (if (IS_SCALAR(VAR)) then {floor (VAR) == (VAR)} else {false})
+#define IS_NUMBER(VAR) IS_SCALAR(VAR)
+
+#define FLOAT_TO_STRING(num) (if (_this == 0) then {"0"} else {str parseNumber (str (_this % _this) + str floor abs _this) + "." + (str (abs _this - floor abs _this) select [2]) + "0"})
+
+/* -------------------------------------------
+Macro: SCRIPT()
+ Sets name of script (relies on PREFIX and COMPONENT values being #defined).
+ Define 'SKIP_SCRIPT_NAME' to skip adding scriptName.
+
+Parameters:
+ NAME - Name of script [Indentifier]
+
+Example:
+ (begin example)
+ SCRIPT(eradicateMuppets);
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#ifndef SKIP_SCRIPT_NAME
+ #define SCRIPT(NAME) scriptName 'PREFIX\COMPONENT\NAME'
+#else
+ #define SCRIPT(NAME) /* nope */
+#endif
+
+/* -------------------------------------------
+Macros: EXPLODE_n()
+ DEPRECATED - Use param/params commands added in Arma 3 1.48
+
+ Splitting an ARRAY into a number of variables (A, B, C, etc).
+
+ Note that this NOT does make the created variables private.
+ _PVT variants do.
+
+ EXPLODE_1(ARRAY,A,B) - Split a 1-element array into separate variable.
+ EXPLODE_2(ARRAY,A,B) - Split a 2-element array into separate variables.
+ EXPLODE_3(ARRAY,A,B,C) - Split a 3-element array into separate variables.
+ EXPLODE_4(ARRAY,A,B,C,D) - Split a 4-element array into separate variables.
+ EXPLODE_5(ARRAY,A,B,C,D,E) - Split a 5-element array into separate variables.
+ EXPLODE_6(ARRAY,A,B,C,D,E,F) - Split a 6-element array into separate variables.
+ EXPLODE_7(ARRAY,A,B,C,D,E,F,G) - Split a 7-element array into separate variables.
+ EXPLODE_8(ARRAY,A,B,C,D,E,F,G,H) - Split a 8-element array into separate variables.
+ EXPLODE_9(ARRAY,A,B,C,D,E,F,G,H,I) - Split a 9-element array into separate variables.
+
+Parameters:
+ ARRAY - Array to read from [Array]
+ A..H - Names of variables to set from array [Identifier]
+
+Example:
+ (begin example)
+ _array = ["fred", 156.8, 120.9];
+ EXPLODE_3(_array,_name,_height,_weight);
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define EXPLODE_1_SYS(ARRAY,A) A = ARRAY param [0]
+#define EXPLODE_1(ARRAY,A) EXPLODE_1_SYS(ARRAY,A); TRACE_1("EXPLODE_1, " + QUOTE(ARRAY),A)
+#define EXPLODE_1_PVT(ARRAY,A) ARRAY params [#A]; TRACE_1("EXPLODE_1, " + QUOTE(ARRAY),A)
+
+#define EXPLODE_2_SYS(ARRAY,A,B) EXPLODE_1_SYS(ARRAY,A); B = ARRAY param [1]
+#define EXPLODE_2(ARRAY,A,B) EXPLODE_2_SYS(ARRAY,A,B); TRACE_2("EXPLODE_2, " + QUOTE(ARRAY),A,B)
+#define EXPLODE_2_PVT(ARRAY,A,B) ARRAY params [#A,#B]; TRACE_2("EXPLODE_2, " + QUOTE(ARRAY),A,B)
+
+#define EXPLODE_3_SYS(ARRAY,A,B,C) EXPLODE_2_SYS(ARRAY,A,B); C = ARRAY param [2]
+#define EXPLODE_3(ARRAY,A,B,C) EXPLODE_3_SYS(ARRAY,A,B,C); TRACE_3("EXPLODE_3, " + QUOTE(ARRAY),A,B,C)
+#define EXPLODE_3_PVT(ARRAY,A,B,C) ARRAY params [#A,#B,#C]; TRACE_3("EXPLODE_3, " + QUOTE(ARRAY),A,B,C)
+
+#define EXPLODE_4_SYS(ARRAY,A,B,C,D) EXPLODE_3_SYS(ARRAY,A,B,C); D = ARRAY param [3]
+#define EXPLODE_4(ARRAY,A,B,C,D) EXPLODE_4_SYS(ARRAY,A,B,C,D); TRACE_4("EXPLODE_4, " + QUOTE(ARRAY),A,B,C,D)
+#define EXPLODE_4_PVT(ARRAY,A,B,C,D) ARRAY params [#A,#B,#C,#D]; TRACE_4("EXPLODE_4, " + QUOTE(ARRAY),A,B,C,D)
+
+#define EXPLODE_5_SYS(ARRAY,A,B,C,D,E) EXPLODE_4_SYS(ARRAY,A,B,C,D); E = ARRAY param [4]
+#define EXPLODE_5(ARRAY,A,B,C,D,E) EXPLODE_5_SYS(ARRAY,A,B,C,D,E); TRACE_5("EXPLODE_5, " + QUOTE(ARRAY),A,B,C,D,E)
+#define EXPLODE_5_PVT(ARRAY,A,B,C,D,E) ARRAY params [#A,#B,#C,#D,#E]; TRACE_5("EXPLODE_5, " + QUOTE(ARRAY),A,B,C,D,E)
+
+#define EXPLODE_6_SYS(ARRAY,A,B,C,D,E,F) EXPLODE_5_SYS(ARRAY,A,B,C,D,E); F = ARRAY param [5]
+#define EXPLODE_6(ARRAY,A,B,C,D,E,F) EXPLODE_6_SYS(ARRAY,A,B,C,D,E,F); TRACE_6("EXPLODE_6, " + QUOTE(ARRAY),A,B,C,D,E,F)
+#define EXPLODE_6_PVT(ARRAY,A,B,C,D,E,F) ARRAY params [#A,#B,#C,#D,#E,#F]; TRACE_6("EXPLODE_6, " + QUOTE(ARRAY),A,B,C,D,E,F)
+
+#define EXPLODE_7_SYS(ARRAY,A,B,C,D,E,F,G) EXPLODE_6_SYS(ARRAY,A,B,C,D,E,F); G = ARRAY param [6]
+#define EXPLODE_7(ARRAY,A,B,C,D,E,F,G) EXPLODE_7_SYS(ARRAY,A,B,C,D,E,F,G); TRACE_7("EXPLODE_7, " + QUOTE(ARRAY),A,B,C,D,E,F,G)
+#define EXPLODE_7_PVT(ARRAY,A,B,C,D,E,F,G) ARRAY params [#A,#B,#C,#D,#E,#F,#G]; TRACE_7("EXPLODE_7, " + QUOTE(ARRAY),A,B,C,D,E,F,G)
+
+#define EXPLODE_8_SYS(ARRAY,A,B,C,D,E,F,G,H) EXPLODE_7_SYS(ARRAY,A,B,C,D,E,F,G); H = ARRAY param [7]
+#define EXPLODE_8(ARRAY,A,B,C,D,E,F,G,H) EXPLODE_8_SYS(ARRAY,A,B,C,D,E,F,G,H); TRACE_8("EXPLODE_8, " + QUOTE(ARRAY),A,B,C,D,E,F,G,H)
+#define EXPLODE_8_PVT(ARRAY,A,B,C,D,E,F,G,H) ARRAY params [#A,#B,#C,#D,#E,#F,#G,#H]; TRACE_8("EXPLODE_8, " + QUOTE(ARRAY),A,B,C,D,E,F,G,H)
+
+#define EXPLODE_9_SYS(ARRAY,A,B,C,D,E,F,G,H,I) EXPLODE_8_SYS(ARRAY,A,B,C,D,E,F,G,H); I = ARRAY param [8]
+#define EXPLODE_9(ARRAY,A,B,C,D,E,F,G,H,I) EXPLODE_9_SYS(ARRAY,A,B,C,D,E,F,G,H,I); TRACE_9("EXPLODE_9, " + QUOTE(ARRAY),A,B,C,D,E,F,G,H,I)
+#define EXPLODE_9_PVT(ARRAY,A,B,C,D,E,F,G,H,I) ARRAY params [#A,#B,#C,#D,#E,#F,#G,#H,#I]; TRACE_9("EXPLODE_9, " + QUOTE(ARRAY),A,B,C,D,E,F,G,H,I)
+
+/* -------------------------------------------
+Macro: xSTRING()
+ Get full string identifier from a stringtable owned by this component.
+
+Parameters:
+ VARIABLE - Partial name of global variable owned by this component [Any].
+
+Example:
+ ADDON is CBA_Balls.
+ (begin example)
+ // Localized String (localize command must still be used with it)
+ LSTRING(Example); // STR_CBA_Balls_Example;
+ // Config String (note the $)
+ CSTRING(Example); // $STR_CBA_Balls_Example;
+ (end)
+
+Author:
+ Jonpas
+------------------------------------------- */
+#ifndef STRING_MACROS_GUARD
+#define STRING_MACROS_GUARD
+ #define LSTRING(var1) QUOTE(TRIPLES(STR,ADDON,var1))
+ #define ELSTRING(var1,var2) QUOTE(TRIPLES(STR,DOUBLES(PREFIX,var1),var2))
+ #define CSTRING(var1) QUOTE(TRIPLES($STR,ADDON,var1))
+ #define ECSTRING(var1,var2) QUOTE(TRIPLES($STR,DOUBLES(PREFIX,var1),var2))
+ #define SUBCSTRING(var1) QUOTE(TRIPLES($STR,SUBADDON,var1))
+
+ #define LLSTRING(var1) localize QUOTE(TRIPLES(STR,ADDON,var1))
+ #define LELSTRING(var1,var2) localize QUOTE(TRIPLES(STR,DOUBLES(PREFIX,var1),var2))
+ #define LSUBLSTRING(var1) localize QUOTE(TRIPLES(STR,SUBADDON,var1))
+#endif
+
+
+/* -------------------------------------------
+Group: Managing Function Parameters
+------------------------------------------- */
+
+/* -------------------------------------------
+Macros: PARAMS_n()
+ DEPRECATED - Use param/params commands added in Arma 3 1.48
+
+ Setting variables based on parameters passed to a function.
+
+ Each parameter is defines as private and set to the appropriate value from _this.
+
+ PARAMS_1(A) - Get 1 parameter from the _this array (or _this if it's not an array).
+ PARAMS_2(A,B) - Get 2 parameters from the _this array.
+ PARAMS_3(A,B,C) - Get 3 parameters from the _this array.
+ PARAMS_4(A,B,C,D) - Get 4 parameters from the _this array.
+ PARAMS_5(A,B,C,D,E) - Get 5 parameters from the _this array.
+ PARAMS_6(A,B,C,D,E,F) - Get 6 parameters from the _this array.
+ PARAMS_7(A,B,C,D,E,F,G) - Get 7 parameters from the _this array.
+ PARAMS_8(A,B,C,D,E,F,G,H) - Get 8 parameters from the _this array.
+
+Parameters:
+ A..H - Name of variable to read from _this [Identifier]
+
+Example:
+ A function called like this:
+ (begin example)
+ [_name,_address,_telephone] call recordPersonalDetails;
+ (end)
+ expects 3 parameters and those variables could be initialised at the start of the function definition with:
+ (begin example)
+ recordPersonalDetails = {
+ PARAMS_3(_name,_address,_telephone);
+ // Rest of function follows...
+ };
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define PARAMS_1(A) EXPLODE_1_PVT(_this,A)
+#define PARAMS_2(A,B) EXPLODE_2_PVT(_this,A,B)
+#define PARAMS_3(A,B,C) EXPLODE_3_PVT(_this,A,B,C)
+#define PARAMS_4(A,B,C,D) EXPLODE_4_PVT(_this,A,B,C,D)
+#define PARAMS_5(A,B,C,D,E) EXPLODE_5_PVT(_this,A,B,C,D,E)
+#define PARAMS_6(A,B,C,D,E,F) EXPLODE_6_PVT(_this,A,B,C,D,E,F)
+#define PARAMS_7(A,B,C,D,E,F,G) EXPLODE_7_PVT(_this,A,B,C,D,E,F,G)
+#define PARAMS_8(A,B,C,D,E,F,G,H) EXPLODE_8_PVT(_this,A,B,C,D,E,F,G,H)
+#define PARAMS_9(A,B,C,D,E,F,G,H,I) EXPLODE_9_PVT(_this,A,B,C,D,E,F,G,H,I)
+
+/* -------------------------------------------
+Macro: DEFAULT_PARAM()
+ DEPRECATED - Use param/params commands added in Arma 3 1.48
+
+ Getting a default function parameter. This may be used together with to have a mix of required and
+ optional parameters.
+
+Parameters:
+ INDEX - Index of parameter in _this [Integer, 0+]
+ NAME - Name of the variable to set [Identifier]
+ DEF_VALUE - Default value to use in case the array is too short or the value at INDEX is nil [Any]
+
+Example:
+ A function called with optional parameters:
+ (begin example)
+ [_name] call myFunction;
+ [_name, _numberOfLegs] call myFunction;
+ [_name, _numberOfLegs, _hasAHead] call myFunction;
+ (end)
+ 1 required parameter and 2 optional parameters. Those variables could be initialised at the start of the function
+ definition with:
+ (begin example)
+ myFunction = {
+ PARAMS_1(_name);
+ DEFAULT_PARAM(1,_numberOfLegs,2);
+ DEFAULT_PARAM(2,_hasAHead,true);
+ // Rest of function follows...
+ };
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define DEFAULT_PARAM(INDEX,NAME,DEF_VALUE) \
+ private [#NAME,"_this"]; \
+ ISNILS(_this,[]); \
+ NAME = _this param [INDEX, DEF_VALUE]; \
+ TRACE_3("DEFAULT_PARAM",INDEX,NAME,DEF_VALUE)
+
+/* -------------------------------------------
+Macro: KEY_PARAM()
+ Get value from key in _this list, return default when key is not included in list.
+
+Parameters:
+ KEY - Key name [String]
+ NAME - Name of the variable to set [Identifier]
+ DEF_VALUE - Default value to use in case key not found [ANY]
+
+Example:
+
+
+Author:
+ Muzzleflash
+------------------------------------------- */
+#define KEY_PARAM(KEY,NAME,DEF_VALUE) \
+ private #NAME; \
+ NAME = [toLower KEY, toUpper KEY, DEF_VALUE, RETNIL(_this)] call CBA_fnc_getArg; \
+ TRACE_3("KEY_PARAM",KEY,NAME,DEF_VALUE)
+
+/* -------------------------------------------
+Group: Assertions
+------------------------------------------- */
+
+#define ASSERTION_ERROR(MESSAGE) ERROR_WITH_TITLE("Assertion failed!",MESSAGE)
+
+/* -------------------------------------------
+Macro: ASSERT_TRUE()
+ Asserts that a CONDITION is true. When an assertion fails, an error is raised with the given MESSAGE.
+
+Parameters:
+ CONDITION - Condition to assert as true [Boolean]
+ MESSSAGE - Message to display if (A OPERATOR B) is false [String]
+
+Example:
+ (begin example)
+ ASSERT_TRUE(_frogIsDead,"The frog is alive");
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define ASSERT_TRUE(CONDITION,MESSAGE) \
+ if (not (CONDITION)) then \
+ { \
+ ASSERTION_ERROR('Assertion (CONDITION) failed!\n\n' + (MESSAGE)); \
+ }
+
+/* -------------------------------------------
+Macro: ASSERT_FALSE()
+ Asserts that a CONDITION is false. When an assertion fails, an error is raised with the given MESSAGE.
+
+Parameters:
+ CONDITION - Condition to assert as false [Boolean]
+ MESSSAGE - Message to display if (A OPERATOR B) is true [String]
+
+Example:
+ (begin example)
+ ASSERT_FALSE(_frogIsDead,"The frog died");
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define ASSERT_FALSE(CONDITION,MESSAGE) \
+ if (CONDITION) then \
+ { \
+ ASSERTION_ERROR('Assertion (not (CONDITION)) failed!\n\n' + (MESSAGE)) \
+ }
+
+/* -------------------------------------------
+Macro: ASSERT_OP()
+ Asserts that (A OPERATOR B) is true. When an assertion fails, an error is raised with the given MESSAGE.
+
+Parameters:
+ A - First value [Any]
+ OPERATOR - Binary operator to use [Operator]
+ B - Second value [Any]
+ MESSSAGE - Message to display if (A OPERATOR B) is false. [String]
+
+Example:
+ (begin example)
+ ASSERT_OP(_fish,>,5,"Too few fish!");
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define ASSERT_OP(A,OPERATOR,B,MESSAGE) \
+ if (not ((A) OPERATOR (B))) then \
+ { \
+ ASSERTION_ERROR('Assertion (A OPERATOR B) failed!\n' + 'A: ' + (str (A)) + '\n' + 'B: ' + (str (B)) + "\n\n" + (MESSAGE)); \
+ }
+
+/* -------------------------------------------
+Macro: ASSERT_DEFINED()
+ Asserts that a VARIABLE is defined. When an assertion fails, an error is raised with the given MESSAGE..
+
+Parameters:
+ VARIABLE - Variable to test if defined [String or Function].
+ MESSAGE - Message to display if variable is undefined [String].
+
+Examples:
+ (begin example)
+ ASSERT_DEFINED("_anUndefinedVar","Too few fish!");
+ ASSERT_DEFINED({ obj getVariable "anUndefinedVar" },"Too many fish!");
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define ASSERT_DEFINED(VARIABLE,MESSAGE) \
+ if (isNil VARIABLE) then \
+ { \
+ ASSERTION_ERROR('Assertion (VARIABLE is defined) failed!\n\n' + (MESSAGE)); \
+ }
+
+/* -------------------------------------------
+Group: Unit tests
+------------------------------------------- */
+#define TEST_SUCCESS(MESSAGE) MESSAGE_WITH_TITLE("Test OK",MESSAGE)
+#define TEST_FAIL(MESSAGE) ERROR_WITH_TITLE("Test FAIL",MESSAGE)
+
+/* -------------------------------------------
+Macro: TEST_TRUE()
+ Tests that a CONDITION is true.
+ If the condition is not true, an error is raised with the given MESSAGE.
+
+Parameters:
+ CONDITION - Condition to assert as true [Boolean]
+ MESSSAGE - Message to display if (A OPERATOR B) is false [String]
+
+Example:
+ (begin example)
+ TEST_TRUE(_frogIsDead,"The frog is alive");
+ (end)
+
+Author:
+ Killswitch
+------------------------------------------- */
+#define TEST_TRUE(CONDITION, MESSAGE) \
+ if (CONDITION) then \
+ { \
+ TEST_SUCCESS('(CONDITION)'); \
+ } \
+ else \
+ { \
+ TEST_FAIL('(CONDITION) ' + (MESSAGE)); \
+ }
+
+/* -------------------------------------------
+Macro: TEST_FALSE()
+ Tests that a CONDITION is false.
+ If the condition is not false, an error is raised with the given MESSAGE.
+
+Parameters:
+ CONDITION - Condition to test as false [Boolean]
+ MESSSAGE - Message to display if (A OPERATOR B) is true [String]
+
+Example:
+ (begin example)
+ TEST_FALSE(_frogIsDead,"The frog died");
+ (end)
+
+Author:
+ Killswitch
+------------------------------------------- */
+#define TEST_FALSE(CONDITION, MESSAGE) \
+ if (not (CONDITION)) then \
+ { \
+ TEST_SUCCESS('(not (CONDITION))'); \
+ } \
+ else \
+ { \
+ TEST_FAIL('(not (CONDITION)) ' + (MESSAGE)); \
+ }
+
+/* -------------------------------------------
+Macro: TEST_OP()
+ Tests that (A OPERATOR B) is true.
+ If the test fails, an error is raised with the given MESSAGE.
+
+Parameters:
+ A - First value [Any]
+ OPERATOR - Binary operator to use [Operator]
+ B - Second value [Any]
+ MESSSAGE - Message to display if (A OPERATOR B) is false. [String]
+
+Example:
+ (begin example)
+ TEST_OP(_fish,>,5,"Too few fish!");
+ (end)
+
+Author:
+ Killswitch
+------------------------------------------- */
+#define TEST_OP(A,OPERATOR,B,MESSAGE) \
+ if ((A) OPERATOR (B)) then \
+ { \
+ TEST_SUCCESS('(A OPERATOR B)') \
+ } \
+ else \
+ { \
+ TEST_FAIL('(A OPERATOR B)') \
+ };
+
+/* -------------------------------------------
+Macro: TEST_DEFINED_AND_OP()
+ Tests that A and B are defined and (A OPERATOR B) is true.
+ If the test fails, an error is raised with the given MESSAGE.
+
+Parameters:
+ A - First value [Any]
+ OPERATOR - Binary operator to use [Operator]
+ B - Second value [Any]
+ MESSSAGE - Message to display [String]
+
+Example:
+ (begin example)
+ TEST_OP(_fish,>,5,"Too few fish!");
+ (end)
+
+Author:
+ Killswitch, PabstMirror
+------------------------------------------- */
+#define TEST_DEFINED_AND_OP(A,OPERATOR,B,MESSAGE) \
+ if (isNil #A) then { \
+ TEST_FAIL('(A is not defined) ' + (MESSAGE)); \
+ } else { \
+ if (isNil #B) then { \
+ TEST_FAIL('(B is not defined) ' + (MESSAGE)); \
+ } else { \
+ if ((A) OPERATOR (B)) then { \
+ TEST_SUCCESS('(A OPERATOR B) ' + (MESSAGE)) \
+ } else { \
+ TEST_FAIL('(A OPERATOR B) ' + (MESSAGE)) \
+ }; }; };
+
+
+/* -------------------------------------------
+Macro: TEST_DEFINED()
+ Tests that a VARIABLE is defined.
+
+Parameters:
+ VARIABLE - Variable to test if defined [String or Function].
+ MESSAGE - Message to display if variable is undefined [String].
+
+Examples:
+ (begin example)
+ TEST_DEFINED("_anUndefinedVar","Too few fish!");
+ TEST_DEFINED({ obj getVariable "anUndefinedVar" },"Too many fish!");
+ (end)
+
+Author:
+ Killswitch
+------------------------------------------- */
+#define TEST_DEFINED(VARIABLE,MESSAGE) \
+ if (not isNil VARIABLE) then \
+ { \
+ TEST_SUCCESS('(' + VARIABLE + ' is defined)'); \
+ } \
+ else \
+ { \
+ TEST_FAIL('(' + VARIABLE + ' is not defined)' + (MESSAGE)); \
+ }
+
+/* -------------------------------------------
+Group: Managing Deprecation
+------------------------------------------- */
+
+/* -------------------------------------------
+Macro: DEPRECATE_SYS()
+ Allow deprecation of a function that has been renamed.
+
+ Replaces an old OLD_FUNCTION (which will have PREFIX_ prepended) with a NEW_FUNCTION
+ (PREFIX_ prepended) with the intention that the old function will be disabled in the future.
+
+ Shows a warning in RPT each time the deprecated function is used, but runs the new function.
+
+Parameters:
+ OLD_FUNCTION - Full name of old function [Identifier for function that does not exist any more]
+ NEW_FUNCTION - Full name of new function [Function]
+
+Example:
+ (begin example)
+ // After renaming CBA_fnc_frog as CBA_fnc_fish
+ DEPRECATE_SYS(CBA_fnc_frog,CBA_fnc_fish);
+ (end)
+
+Author:
+ Sickboy
+------------------------------------------- */
+#define DEPRECATE_SYS(OLD_FUNCTION,NEW_FUNCTION) \
+ OLD_FUNCTION = { \
+ WARNING('Deprecated function used: OLD_FUNCTION (new: NEW_FUNCTION) in ADDON'); \
+ if (isNil "_this") then { call NEW_FUNCTION } else { _this call NEW_FUNCTION }; \
+ }
+
+/* -------------------------------------------
+Macro: DEPRECATE()
+ Allow deprecation of a function, in the current component, that has been renamed.
+
+ Replaces an OLD_FUNCTION (which will have PREFIX_ prepended) with a NEW_FUNCTION
+ (PREFIX_ prepended) with the intention that the old function will be disabled in the future.
+
+ Shows a warning in RPT each time the deprecated function is used, but runs the new function.
+
+Parameters:
+ OLD_FUNCTION - Name of old function, assuming PREFIX [Identifier for function that does not exist any more]
+ NEW_FUNCTION - Name of new function, assuming PREFIX [Function]
+
+Example:
+ (begin example)
+ // After renaming CBA_fnc_frog as CBA_fnc_fish
+ DEPRECATE(fnc_frog,fnc_fish);
+ (end)
+
+Author:
+ Sickboy
+------------------------------------------- */
+#define DEPRECATE(OLD_FUNCTION,NEW_FUNCTION) \
+ DEPRECATE_SYS(DOUBLES(PREFIX,OLD_FUNCTION),DOUBLES(PREFIX,NEW_FUNCTION))
+
+/* -------------------------------------------
+Macro: OBSOLETE_SYS()
+ Replace a function that has become obsolete.
+
+ Replace an obsolete OLD_FUNCTION with a simple COMMAND_FUNCTION, with the intention that anyone
+ using the function should replace it with the simple command, since the function will be disabled in the future.
+
+ Shows a warning in RPT each time the deprecated function is used, and runs the command function.
+
+Parameters:
+ OLD_FUNCTION - Full name of old function [Identifier for function that does not exist any more]
+ COMMAND_CODE - Code to replace the old function [Function]
+
+Example:
+ (begin example)
+ // In Arma2, currentWeapon command made the CBA_fMyWeapon function obsolete:
+ OBSOLETE_SYS(CBA_fMyWeapon,{ currentWeapon player });
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define OBSOLETE_SYS(OLD_FUNCTION,COMMAND_CODE) \
+ OLD_FUNCTION = { \
+ WARNING('Obsolete function used: (use: OLD_FUNCTION) in ADDON'); \
+ if (isNil "_this") then { call COMMAND_CODE } else { _this call COMMAND_CODE }; \
+ }
+
+/* -------------------------------------------
+Macro: OBSOLETE()
+ Replace a function, in the current component, that has become obsolete.
+
+ Replace an obsolete OLD_FUNCTION (which will have PREFIX_ prepended) with a simple
+ COMMAND_CODE, with the intention that anyone using the function should replace it with the simple
+ command.
+
+ Shows a warning in RPT each time the deprecated function is used.
+
+Parameters:
+ OLD_FUNCTION - Name of old function, assuming PREFIX [Identifier for function that does not exist any more]
+ COMMAND_CODE - Code to replace the old function [Function]
+
+Example:
+ (begin example)
+ // In Arma2, currentWeapon command made the CBA_fMyWeapon function obsolete:
+ OBSOLETE(fMyWeapon,{ currentWeapon player });
+ (end)
+
+Author:
+ Spooner
+------------------------------------------- */
+#define OBSOLETE(OLD_FUNCTION,COMMAND_CODE) \
+ OBSOLETE_SYS(DOUBLES(PREFIX,OLD_FUNCTION),COMMAND_CODE)
+
+#define BWC_CONFIG(NAME) class NAME { \
+ units[] = {}; \
+ weapons[] = {}; \
+ requiredVersion = REQUIRED_VERSION; \
+ requiredAddons[] = {}; \
+ version = VERSION; \
+}
+
+// XEH Specific
+#define XEH_CLASS CBA_Extended_EventHandlers
+#define XEH_CLASS_BASE DOUBLES(XEH_CLASS,base)
+#define XEH_DISABLED class EventHandlers { class XEH_CLASS {}; }; SLX_XEH_DISABLED = 1
+#define XEH_ENABLED class EventHandlers { class XEH_CLASS { EXTENDED_EVENTHANDLERS }; }; SLX_XEH_DISABLED = 0
+
+// TODO: These are actually outdated; _Once ?
+#define XEH_PRE_INIT QUOTE(call COMPILE_FILE(XEH_PreInit_Once))
+#define XEH_PRE_CINIT QUOTE(call COMPILE_FILE(XEH_PreClientInit_Once))
+#define XEH_PRE_SINIT QUOTE(call COMPILE_FILE(XEH_PreServerInit_Once))
+
+#define XEH_POST_INIT QUOTE(call COMPILE_FILE(XEH_PostInit_Once))
+#define XEH_POST_CINIT QUOTE(call COMPILE_FILE(XEH_PostClientInit_Once))
+#define XEH_POST_SINIT QUOTE(call COMPILE_FILE(XEH_PostServerInit_Once))
+
+/* -------------------------------------------
+Macro: IS_ADMIN
+ Check if the local machine is an admin in the multiplayer environment.
+
+ Reports 'true' for logged and voted in admins.
+
+Parameters:
+ None
+
+Example:
+ (begin example)
+ // print "true" if player is admin
+ systemChat str IS_ADMIN;
+ (end)
+
+Author:
+ commy2
+------------------------------------------- */
+#define IS_ADMIN_SYS(x) x##kick
+#define IS_ADMIN serverCommandAvailable 'IS_ADMIN_SYS(#)'
+
+/* -------------------------------------------
+Macro: IS_ADMIN_LOGGED
+ Check if the local machine is a logged in admin in the multiplayer environment.
+
+ Reports 'false' if the player was voted to be the admin.
+
+Parameters:
+ None
+
+Example:
+ (begin example)
+ // print "true" if player is admin and entered in the server password
+ systemChat str IS_ADMIN_LOGGED;
+ (end)
+
+Author:
+ commy2
+------------------------------------------- */
+#define IS_ADMIN_LOGGED_SYS(x) x##shutdown
+#define IS_ADMIN_LOGGED serverCommandAvailable 'IS_ADMIN_LOGGED_SYS(#)'
+
+/* -------------------------------------------
+Macro: FILE_EXISTS
+ Check if a file exists
+
+ Reports "false" if the file does not exist.
+
+Parameters:
+ FILE - Path to the file
+
+Example:
+ (begin example)
+ // print "true" if file exists
+ systemChat str FILE_EXISTS("\A3\ui_f\data\igui\cfg\cursors\weapon_ca.paa");
+ (end)
+
+Author:
+ commy2
+------------------------------------------- */
+#define FILE_EXISTS(FILE) (fileExists (FILE))
\ No newline at end of file
diff --git a/framework/x/cba/addons/main/script_macros_mission.hpp b/framework/x/cba/addons/main/script_macros_mission.hpp
new file mode 100644
index 0000000..d2eae33
--- /dev/null
+++ b/framework/x/cba/addons/main/script_macros_mission.hpp
@@ -0,0 +1,85 @@
+#include "script_macros_common.hpp"
+
+/*
+ Header: script_macros_mission.hpp
+
+ Description:
+ Modifies script_common_macros.hpp for compatiblity with missions.
+ Some addon specific functionality might be lost.
+
+ Authors:
+ Muzzleflash
+
+ Changes from script_macros_mission.hpp:
+ Follows Standard:
+ Object variables: PREFIX_COMPONENT
+ Main-object variables: PREFIX_main
+ Paths: PREFIX\COMPONENT\SCRIPTNAME.sqf
+ Or if CUSTOM_FOLDER is defined:
+ CUSTOM_FOLDER\SCRIPTNAME.sqf
+ eg. six\sys_menu\fDate.sqf
+
+ Usage:
+ Define PREFIX and COMPONENT, then include this file:
+
+
+*/
+
+/*
+ CUSTOM_FOLDER
+
+ Custom folder to search for files in. Will not change variable names.
+ Default is PREFIX\COMPONENT
+
+ Example:
+ (begin example)
+ #define CUSTOM_FOLDER MyPackage\ScriptA
+ (end)
+
+ (begin example)
+ #define CUSTOM_FOLDER COMPONENT\functions
+ (end)
+
+
+*/
+
+#undef PATHTO_SYS
+#undef PATHTOF_SYS
+#undef PATHTOF2_SYS
+#ifdef CUSTOM_FOLDER
+ #define PATHTO_SYS(var1,var2,var3) ##CUSTOM_FOLDER\##var3.sqf
+ #define PATHTOF_SYS(var1,var2,var3) ##CUSTOM_FOLDER\##var3
+ #define PATHTOF2_SYS(var1,var2,var3) ##CUSTOM_FOLDER\##var3
+#else
+ #define PATHTO_SYS(var1,var2,var3) ##var1\##var2\##var3.sqf
+ #define PATHTOF_SYS(var1,var2,var3) ##var1\##var2\##var3
+ #define PATHTOF2_SYS(var1,var2,var3) ##var1\##var2\##var3
+#endif
+
+/************************** REMOVAL OF MACROS ***********************/
+
+#undef MAINPREFIX
+#undef SUBPREFIX
+#undef VERSION_AR
+#undef VERSION_CONFIG
+
+#undef VERSIONING_SYS
+#undef VERSIONING
+
+#undef PRELOAD_ADDONS
+
+#undef BWC_CONFIG
+
+#undef XEH_DISABLED
+#undef XEH_PRE_INIT
+#undef XEH_PRE_CINIT
+#undef XEH_PRE_SINIT
+#undef XEH_POST_INIT
+#undef XEH_POST_CINIT
+#undef XEH_POST_SINIT
+
+#undef PATHTO_FNC
+#define PATHTO_FNC(func) class func {\
+ file = QUOTE(DOUBLES(fnc,func).sqf);\
+ RECOMPILE;\
+}
\ No newline at end of file