diff --git a/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/client/init.sqf b/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/client/init.sqf
new file mode 100644
index 0000000..201b647
--- /dev/null
+++ b/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/client/init.sqf
@@ -0,0 +1,115 @@
+karma_deployableRadioExtenders_client_currentDeployedRadioExtender = objNull;
+karma_deployableRadioExtenders_client_isPerformingAction = false;
+karma_deployableRadioExtenders_client_actionAnimation = "Acts_TreatingWounded05";
+karma_deployableRadioExtenders_client_actionDurationInSeconds = 10; // This can't be longer than 24 seconds (limitation of the BIS_fnc_holdActionAdd function).
+
+karma_deployableRadioExtenders_client_initializePlayer = {
+ private _deployActionId = [
+ player, // target
+ ["", localize "STR_KARMA_DEPLOY_RADIO_EXTENDER", ""] joinString "", // title
+ "res\ui_build.paa", // idleIcon
+ "res\ui_build.paa", // progressIcon
+ "
+ alive player &&
+ vehicle player == player &&
+ isNull karma_deployableRadioExtenders_client_currentDeployedRadioExtender &&
+ (getPosATL player select 2) < 0.1 &&
+ player getVariable ['karma_canDeployRadioExtender', false];
+ ", // conditionShow
+ "true", // conditionProgress
+ {
+ karma_deployableRadioExtenders_client_isPerformingAction = true;
+ player playMoveNow karma_deployableRadioExtenders_client_actionAnimation;
+ }, // codeStart
+ {}, // codeProgress
+ {
+ [player] remoteExecCall ["karma_deployableRadioExtenders_server_deployRadioExtender", 2];
+ player playActionNow "Stand";
+ karma_deployableRadioExtenders_client_isPerformingAction = false;
+ }, // codeCompleted
+ {
+ player playActionNow "Stand";
+ karma_deployableRadioExtenders_client_isPerformingAction = false;
+ }, // codeInterrupted
+ [], // arguments
+ karma_deployableRadioExtenders_client_actionDurationInSeconds, // duration
+ 100, // priority
+ false, // removeCompleted
+ false, // showUnconscious
+ false // showWindow
+ ] call BIS_fnc_holdActionAdd;
+
+ player setVariable ["karma_deployableRadioExtenders_deployActionId", _deployActionId];
+};
+
+karma_deployableRadioExtenders_client_handleRadioExtenderDeploymentResponse = {
+ params [
+ ["_statusCode", -1],
+ ["_ownerUID", ""],
+ ["_radioExtender", objNull]
+ ];
+
+ if (getPlayerUID player == _ownerUID) then {
+ karma_deployableRadioExtenders_client_currentDeployedRadioExtender = _radioExtender;
+ hint (_statusCode call karma_deployableRadioExtenders_shared_getMessageForStatusCode);
+ };
+
+ if (!isNull _radioExtender) then {
+ // Add the repack action to the radio extender.
+ [
+ _radioExtender, // target
+ ["", localize "STR_KARMA_REPACK_RADIO_EXTENDER", ""] joinString "", // title
+ "res\ui_build.paa", // idleIcon
+ "res\ui_build.paa", // progressIcon
+ "
+ alive player &&
+ vehicle player == player &&
+ player getVariable ['karma_canDeployRadioExtender', false] &&
+ getPlayerUID player == (_target getVariable ['karma_ownerUID', '']);
+ ", // conditionShow
+ "true", // conditionProgress
+ {
+ karma_deployableRadioExtenders_client_isPerformingAction = true;
+ player playMoveNow karma_deployableRadioExtenders_client_actionAnimation;
+ }, // codeStart
+ {}, // codeProgress
+ {
+ [player] remoteExecCall ["karma_deployableRadioExtenders_server_repackRadioExtender", 2];
+ player playActionNow "Stand";
+ karma_deployableRadioExtenders_client_isPerformingAction = false;
+ }, // codeCompleted
+ {
+ player playActionNow "Stand";
+ karma_deployableRadioExtenders_client_isPerformingAction = false;
+ }, // codeInterrupted
+ [], // arguments
+ karma_deployableRadioExtenders_client_actionDurationInSeconds, // duration
+ 100, // priority
+ false, // removeCompleted
+ false, // showUnconscious
+ false // showWindow
+ ] call BIS_fnc_holdActionAdd;
+ };
+};
+
+karma_deployableRadioExtenders_client_handleRadioExtenderRepackResponse = {
+ params [
+ ["_statusCode", -1],
+ ["_ownerUID", objNull]
+ ];
+
+ if (getPlayerUID player == _ownerUID) then {
+ karma_deployableRadioExtenders_client_currentDeployedRadioExtender = objNull;
+ hint (_statusCode call karma_deployableRadioExtenders_shared_getMessageForStatusCode);
+ };
+};
+
+[] call karma_deployableRadioExtenders_client_initializePlayer;
+player addEventHandler ["Respawn", {
+ params ["_unit", "_corpse"];
+ if (player != unit) exitWith {};
+ private _deployActionId = _corpse getVariable ["karma_deployableRadioExtenders_deployActionId", -1];
+ if (_deployActionId == -1) exitWith {};
+ [_corpse, _deployActionId] call BIS_fnc_holdActionRemove;
+ [] call karma_deployableRadioExtenders_client_initializePlayer;
+}];
\ No newline at end of file
diff --git a/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/readme.md b/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/readme.md
new file mode 100644
index 0000000..514b8d0
--- /dev/null
+++ b/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/readme.md
@@ -0,0 +1,12 @@
+# Deployable Radio Extenders
+
+## Description
+Provides units with the variable `karma_canDeployRadioExtender` set to `true` to deploy radio extenders anywhere via the action menu.
+Deployed radio extenders can then be repacked and deployed again.
+Only one radio extender is allowed to be deployed at a time per engineer.
+
+## Enabling radio extender deployment for a unit
+To allow a unit to deploy a radio extender, add the following to their init via the editor:
+```sqf
+this setVariable ["karma_canDeployRadioExtender", true];
+```
diff --git a/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/server/init.sqf b/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/server/init.sqf
new file mode 100644
index 0000000..74b70ba
--- /dev/null
+++ b/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/server/init.sqf
@@ -0,0 +1,62 @@
+karma_deployableRadioExtenders_server_radioExtendersByPlayerUID = createHashMap;
+
+karma_deployableRadioExtenders_server_deployRadioExtender = {
+ params [
+ ["_player", objNull]
+ ];
+
+ if (isNull _player) exitWith {};
+
+ private _playerUID = getPlayerUID _player;
+ private _existingRadioExtender = karma_deployableRadioExtenders_server_radioExtendersByPlayerUID getOrDefault [_playerUID, objNull];
+ if (!isNull _existingRadioExtender) exitWith {
+ [
+ karma_deployableRadioExtenders_shared_statusCodes_radioExtenderAlreadyDeployed,
+ _playerUID,
+ _existingRadioExtender
+ ] remoteExecCall ["karma_deployableRadioExtenders_client_handleRadioExtenderDeploymentResponse"];
+ };
+
+ private _distanceFromPlayerToTerrain = getPosATL _player select 2;
+ if (_distanceFromPlayerToTerrain > 0.1) exitWith {
+ [
+ karma_deployableRadioExtenders_shared_statusCodes_playerNotOnTerrain,
+ _playerUID
+ ] remoteExecCall ["karma_deployableRadioExtenders_client_handleRadioExtenderDeploymentResponse"];
+ };
+
+ private _playerPosition = position _player;
+ private _playerDirection = direction _player;
+ private _radioExtender = karma_deployableRadioExtenders_shared_radioExtenderClassname createVehicle _playerPosition;
+ _radioExtender allowDamage false;
+ _radioExtender setDir _playerDirection;
+ _radioExtender setPos (_playerPosition vectorAdd (vectorDir _player));
+ _radioExtender setVariable ["karma_ownerUID", _playerUID, true];
+ karma_deployableRadioExtenders_server_radioExtendersByPlayerUID set [_playerUID, _radioExtender];
+
+ [
+ karma_deployableRadioExtenders_shared_statusCodes_radioExtenderDeployed,
+ _playerUID,
+ _radioExtender
+ ] remoteExecCall ["karma_deployableRadioExtenders_client_handleRadioExtenderDeploymentResponse"];
+};
+
+karma_deployableRadioExtenders_server_repackRadioExtender = {
+ params [
+ ["_player", objNull]
+ ];
+
+ if (isNull _player) exitWith {};
+
+ private _playerUID = getPlayerUID _player;
+ private _radioExtender = karma_deployableRadioExtenders_server_radioExtendersByPlayerUID getOrDefault [_playerUID, objNull];
+ karma_deployableRadioExtenders_server_radioExtendersByPlayerUID deleteAt _playerUID;
+ if (!isNull _radioExtender) then {
+ deleteVehicle _radioExtender;
+ };
+
+ [
+ karma_deployableRadioExtenders_shared_statusCodes_radioExtenderRepacked,
+ _playerUID
+ ] remoteExecCall ["karma_deployableRadioExtenders_client_handleRadioExtenderRepackResponse"];
+};
\ No newline at end of file
diff --git a/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/shared/init.sqf b/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/shared/init.sqf
new file mode 100644
index 0000000..d964acc
--- /dev/null
+++ b/KC_Liberation_Master_Framework/karmakut/deployable_radio_extenders/shared/init.sqf
@@ -0,0 +1,31 @@
+karma_deployableRadioExtenders_shared_radioExtenderClassname = "tfw_rf3080Object";
+
+// Statuses and messaging:
+karma_deployableRadioExtenders_shared_statusCodes_radioExtenderDeployed = 0;
+karma_deployableRadioExtenders_shared_statusCodes_radioExtenderAlreadyDeployed = 1;
+karma_deployableRadioExtenders_shared_statusCodes_radioExtenderRepacked = 2;
+karma_deployableRadioExtenders_shared_statusCodes_playerNotOnTerrain = 3;
+
+karma_deployableRadioExtenders_shared_messagesByStatusCode = createHashMapFromArray [
+ [
+ karma_deployableRadioExtenders_shared_statusCodes_radioExtenderDeployed,
+ localize "STR_KARMA_RADIO_EXTENDER_DEPLOYED"
+ ],
+ [
+ karma_deployableRadioExtenders_shared_statusCodes_radioExtenderAlreadyDeployed,
+ localize "STR_KARMA_RADIO_EXTENDER_ALREADY_DEPLOYED"
+ ],
+ [
+ karma_deployableRadioExtenders_shared_statusCodes_radioExtenderRepacked,
+ localize "STR_KARMA_RADIO_EXTENDER_REPACKED"
+ ],
+ [
+ karma_deployableRadioExtenders_shared_statusCodes_playerNotOnTerrain,
+ localize "STR_KARMA_RADIO_EXTENDER_MUST_BE_DEPLOYED_ON_TERRAIN"
+ ]
+];
+
+karma_deployableRadioExtenders_shared_getMessageForStatusCode = {
+ params ["_statusCode"];
+ karma_deployableRadioExtenders_shared_messagesByStatusCode getOrDefault [_statusCode, "UNKNOWN STATUS"];
+};
\ No newline at end of file
diff --git a/KC_Liberation_Master_Framework/karmakut/init_client.sqf b/KC_Liberation_Master_Framework/karmakut/init_client.sqf
index c4c6507..b37a73e 100644
--- a/KC_Liberation_Master_Framework/karmakut/init_client.sqf
+++ b/KC_Liberation_Master_Framework/karmakut/init_client.sqf
@@ -1,2 +1,3 @@
[] call compileFinal preProcessFileLineNumbers "karmakut\deployable_field_hospitals\client\init.sqf";
+[] call compileFinal preProcessFileLineNumbers "karmakut\deployable_radio_extenders\client\init.sqf";
[] call compileFinal preProcessFileLineNumbers "karmakut\trash_cleanup\client\init.sqf";
\ No newline at end of file
diff --git a/KC_Liberation_Master_Framework/karmakut/init_server.sqf b/KC_Liberation_Master_Framework/karmakut/init_server.sqf
index 3678a7b..75527b9 100644
--- a/KC_Liberation_Master_Framework/karmakut/init_server.sqf
+++ b/KC_Liberation_Master_Framework/karmakut/init_server.sqf
@@ -1,2 +1,3 @@
[] call compileFinal preProcessFileLineNumbers "karmakut\deployable_field_hospitals\server\init.sqf";
+[] call compileFinal preProcessFileLineNumbers "karmakut\deployable_radio_extenders\server\init.sqf";
[] call compileFinal preProcessFileLineNumbers "karmakut\trash_cleanup\server\init.sqf";
\ No newline at end of file
diff --git a/KC_Liberation_Master_Framework/karmakut/init_shared.sqf b/KC_Liberation_Master_Framework/karmakut/init_shared.sqf
index 5dffd52..31e2726 100644
--- a/KC_Liberation_Master_Framework/karmakut/init_shared.sqf
+++ b/KC_Liberation_Master_Framework/karmakut/init_shared.sqf
@@ -1,2 +1,3 @@
[] call compileFinal preProcessFileLineNumbers "karmakut\deployable_field_hospitals\shared\init.sqf";
+[] call compileFinal preProcessFileLineNumbers "karmakut\deployable_radio_extenders\shared\init.sqf";
[] call compileFinal preProcessFileLineNumbers "karmakut\trash_cleanup\shared\init.sqf";
\ No newline at end of file
diff --git a/KC_Liberation_Master_Framework/stringtable.xml b/KC_Liberation_Master_Framework/stringtable.xml
index 1c2a516..6105f76 100644
--- a/KC_Liberation_Master_Framework/stringtable.xml
+++ b/KC_Liberation_Master_Framework/stringtable.xml
@@ -7356,5 +7356,23 @@
Los hospitales de campaña solo se pueden desplegar en el terreno.
Polní nemocnice lze nasadit pouze v terénu.
+
+ Deploy Radio Extender
+
+
+ Repack Radio Extender
+
+
+ Radio Extender Deployed
+
+
+ Please repack your current radio extender before deploying a new one.
+
+
+ Radio Extender Repacked
+
+
+ Radio extenders can only be deployed on terrain.
+