Преглед изворни кода

Merge pull request #143 from 501st-Aux-Mod-Team/add-unpackable-medical-tent

Add unpackable medical tent
Erliens пре 4 година
родитељ
комит
53cb084362

+ 22 - 0
addons - Copy/RD501_Main/XEH_postinit.sqf

@@ -45,5 +45,27 @@ rd501_flip_vehicle_validBackpacks = ["RD501_JLTS_Clone_Flip_backpack"];
 // Fortify Tool Adjustments
 call macro_fnc_name(fortify_tool);
 
+// Medical CCP Building
+rd501_medical_ccp_building = "Land_Medevac_house_V1_F";
+rd501_medical_ccp_classes = ["Land_Medevac_house_V1_F"];
+rd501_medical_ccp_stitchDurationSeconds = 10;
+rd501_medical_ccp_bandageDurationSeconds = 10;
+
+["rd501_medical_ccp_incrementStitch",{ 
+	_this call rd501_fnc_incrementStitchProgress 
+}] call CBA_fnc_addEventHandler;
+
+["rd501_medical_ccp_incrementBandage",{
+	_this call rd501_fnc_incrementBandageProgress
+}] call CBA_fnc_addEventHandler;
+
+["rd501_medical_ccp_deployCCPLocal", {
+	_this call rd501_fnc_deployCCPLocal;
+}] call CBA_fnc_addEventHandler;
+
+["rd501_medical_ccp_deployCCPServer", {
+	_this call rd501_fnc_deployCCPServer;
+}] call CBA_fnc_addEventHandler;
+
 // Surrender stun
 call macro_fnc_name(stun);

+ 18 - 0
addons - Copy/RD501_Main/XEH_preInit.sqf

@@ -120,3 +120,21 @@ macro_prep_xeh(heal_nearby\fnc_healAllNearby.sqf,healAllNearby)
 
 // stun
 macro_prep_xeh(stun\stun.sqf,stun)
+
+// Medical CCP
+macro_prep_xeh(medical_ccp\fnc_stitchAllWounds.sqf,stitchAllWounds)
+macro_prep_xeh(medical_ccp\fnc_bandageAllWounds.sqf,bandageAllWounds)
+macro_prep_xeh(medical_ccp\fnc_checkInsideCCP.sqf,checkInsideCCP)
+macro_prep_xeh(medical_ccp\fnc_stitchAllWoundsNearbyCCP.sqf,stitchAllWoundsNearbyCCP)
+macro_prep_xeh(medical_ccp\fnc_bandageAllNearbyCCP.sqf,bandageAllNearbyCCP)
+macro_prep_xeh(medical_ccp\fnc_valueProgressBar.sqf,valueProgressBar)
+macro_prep_xeh(medical_ccp\fnc_incrementBandageProgress.sqf,incrementBandageProgress)
+macro_prep_xeh(medical_ccp\fnc_incrementStitchProgress.sqf,incrementStitchProgress)
+macro_prep_xeh(medical_ccp\fnc_deployCCP.sqf,deployCCP)
+macro_prep_xeh(medical_ccp\fnc_deployCCPLocal.sqf,deployCCPLocal)
+macro_prep_xeh(medical_ccp\fnc_deployCCPServer.sqf,deployCCPServer)
+macro_prep_xeh(medical_ccp\fnc_isDoctor.sqf,isDoctor)
+macro_prep_xeh(medical_ccp\fnc_canBandageNearbyCCP.sqf,canBandageNearbyCCP)
+macro_prep_xeh(medical_ccp\fnc_canStitchNearbyCCP.sqf,canStitchNearbyCCP)
+
+diag_log "RD501 PREP Complete";

+ 103 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_bandageAllNearbyCCP.sqf

@@ -0,0 +1,103 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Healer
+ * Origin To Search from
+ * Radius To Search Around for People
+ * Return Value:
+ * Nothing
+ *
+ * Example:
+ * [player, cursorTarget] call rd501_fnc_bandageAllNearbyCCP
+ *
+ * Public: No
+ */
+
+params["_healer", "_origin", "_radius"];
+
+private _nearbyPatients = _origin nearEntities ["CAManBase", _radius] select {
+	[_x] call rd501_fnc_checkInsideCCP &&
+	{
+		count (_x getVariable ["ace_medical_openWounds", []]) > 0
+	}
+};
+
+private _args = [_healer, _nearbyPatients, _origin];
+
+if(count _nearbyPatients == 0) exitWith {
+	["Nobody to Bandage Inside CCP", true, 2, 0] call ace_common_fnc_displayText;
+};
+
+[format["Bandaging %1 Patient(s)", count _nearbyPatients], false, 10, 0] call ace_common_fnc_displayText;
+
+private _onFinish = {
+    (_this select 0) params ["_player", "_patients", "_building"];
+	{
+		if([_x] call rd501_fnc_checkInsideCCP) then {
+			[_player, _x] call rd501_fnc_bandageAllWounds;
+		};
+	} forEach (_patients);
+    _building setVariable ["rd501_medical_ccp_bandageProgress", -1, true];
+    _building setVariable["rd501_medical_ccp_bandageMembers", [], true];
+	[_player, "", 1] call ace_common_fnc_doAnimation;
+};
+
+private _onFailure = {
+    params["_args", "_progress", "_errorCode"];
+    _args params["_healer","_nearbyPatients", "_building"];
+    [_healer, "", 1] call ace_common_fnc_doAnimation;
+    _bandagers = _building getVariable ["rd501_medical_ccp_bandageMembers", []];
+    if(count _bandagers <= 1) then {
+        _building setVariable ["rd501_medical_ccp_bandageProgress", -1, true];
+        _building setVariable ["rd501_medical_ccp_bandageMembers", [], true];
+        _building setVariable ["rd501_medical_ccp_bandageProgressComplete", 100];
+    }
+    else
+    {
+        _newArr = _bandagers deleteAt (_bandagers findIf { _x isEqualTo ([] call CBA_fnc_currentUnit)}) select 1;
+        _building setVariable["rd501_medical_ccp_bandageMembers", _newArr, true];
+    }
+};
+
+private _condition = {
+    params["_args", "_progress", "_errorCode"];
+    _args params["_healer","_nearbyPatients", "_building"];
+    if(_progress == -1) exitWith {false};
+    if(_healer getVariable ["ACE_Unconscious", false]) exitWith {false};
+    alive _healer && alive _building
+};
+
+if(_origin getVariable ["rd501_medical_ccp_bandageProgress", -1] == -1) then {
+    private _bandageDuration = ((count _nearbyPatients) * rd501_medical_ccp_bandageDurationSeconds);
+    _origin setVariable ["rd501_medical_ccp_bandageProgress", 0, true];
+    _origin setVariable ["rd501_medical_ccp_bandageMembers", [player], true];
+    _origin setVariable ["rd501_medical_ccp_bandageProgressComplete", _bandageDuration, true];
+}
+else
+{
+    _bandageMembers = _origin getVariable ["rd501_medical_ccp_bandageMembers", []];
+    _bandageMembers append [player];
+    _origin setVariable ["rd501_medical_ccp_bandageMembers", _bandageMembers, true];
+};
+
+[
+    {
+        params ["_args", "_handle"];
+        _args params ["_healer", "_nearbyPatients", "_origin"];
+        _progress = _origin getVariable ["rd501_medical_ccp_bandageProgress", -1];
+        _progressComplete = _origin getVariable ["rd501_medical_ccp_bandageProgressComplete", 100];
+        if(_progress < 0 || _progress >= _progressComplete) exitWith {
+            [_handle] call CBA_fnc_removePerFrameHandler;
+        };
+        if!(_healer getVariable ["ACE_Unconscious", false]) exitWith {
+            ["rd501_medical_ccp_incrementBandage",[_origin, _healer]] call CBA_fnc_serverEvent;
+        };
+    },
+    1,
+    _args
+] call CBA_fnc_addPerFrameHandler;
+
+[_healer, "AinvPknlMstpSnonWnonDr_medic5", 0] call ace_common_fnc_doAnimation;
+
+["rd501_medical_ccp_bandageProgress", "rd501_medical_ccp_bandageProgressComplete", _origin, _args, _onFinish, _onFailure, "Bandaging All Patients Inside CCP", _condition] call rd501_fnc_valueProgressBar;

+ 28 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_bandageAllWounds.sqf

@@ -0,0 +1,28 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Healer
+ * Patient
+ * Return Value:
+ * Nothing
+ *
+ * Example:
+ * [player, cursorTarget] call rd501_fnc_bandageAllWounds
+ *
+ * Public: No
+ */
+
+params ["_healer", "_patient"];
+
+private _openWounds = (_patient getVariable ["ace_medical_openWounds", []]);
+if (_openWounds isEqualTo []) exitWith {};
+
+_patient setVariable ["ace_medical_bandagedWounds", _openWounds, true];
+_patient setVariable ["ace_medical_openWounds", [], true];
+
+[_patient] call ace_medical_status_fnc_updateWoundBloodLoss;
+[_patient] call ace_medical_engine_fnc_updateDamageEffects;
+
+private _nearPlayers = (_patient nearEntities ["CAManBase", 6]) select {_x call ace_common_fnc_isPlayer};
+["ace_interact_menu_clearConditionCaches", [], _nearPlayers] call CBA_fnc_targetEvent;

+ 19 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_canBandageNearbyCCP.sqf

@@ -0,0 +1,19 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Unit
+ * Return Value:
+ * True if eligable to use bandage all action
+ *
+ * Example:
+ * [cursorTarget, player, []] call rd501_fnc_canBandageNearbyCCP
+ *
+ * Public: No
+ */
+
+params ["_target", "_player", "_params"];
+
+alive _target &&
+{ _player call rd501_fnc_checkInsideCCP } &&
+{ _player call rd501_fnc_isDoctor }

+ 19 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_canStitchNearbyCCP.sqf

@@ -0,0 +1,19 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Unit
+ * Return Value:
+ * True if eligable to use stitch all action
+ *
+ * Example:
+ * [cursorTarget, player, []] call rd501_fnc_canStitchNearbyCCP
+ *
+ * Public: No
+ */
+
+params ["_target", "_player", "_params"];
+
+alive _target &&
+{ _player call rd501_fnc_checkInsideCCP } &&
+{ _player call rd501_fnc_isDoctor }

+ 32 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_checkInsideCCP.sqf

@@ -0,0 +1,32 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Unit to check for
+ * Return Value:
+ * True if inside the bounds of a given structure
+ *
+ * Example:
+ * [player] call rd501_fnc_checkInsideCCP
+ *
+ * Public: No
+ */
+
+params ["_unit"];
+
+private _fnc_check = {
+    private _position = _unit modelToWorldVisual [0, 0, eyePos _unit select 2];
+     
+    (
+        (lineIntersectsWith [_position, _position vectorAdd [0, 0, 10], _unit]) findIf {
+            typeOf _x in rd501_medical_ccp_classes || {_x getVariable ["rd501_medical_ccp_inside", false]}
+        } != -1
+    )
+    || {
+        ((_unit nearObjects 7.5) findIf {
+            typeOf _x in rd501_medical_ccp_classes || {_x getVariable ["rd501_medical_ccp_inside", false]}
+        } != -1)
+    }
+};
+
+[[], _fnc_check, _unit, "rd501_medical_ccp_insideCache", 1] call ace_common_fnc_cachedCall;

+ 31 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_deployCCPLocal.sqf

@@ -0,0 +1,31 @@
+/*
+ * Author: M3ales
+ *
+ * Adds the ace interaction options to the local machine, exits if its a dedicated serverCommand
+ *
+ * Arguments:
+ * CCP Building
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [cursorTarget] call rd501_fnc_deployCCPLocal
+ *
+ * Public: No
+ */
+
+params["_ccp"];
+
+if(isDedicated) exitWith {};
+
+_action = ["rd501_medical_ccp_bandageAll", "Bandage All Patients", "", {
+	params ["_target", "_player", "_params"];
+		[_player, _target, 20] call rd501_fnc_bandageAllNearbyCCP;
+	}, {_this call rd501_fnc_canBandageNearbyCCP}, {[]}] call ace_interact_menu_fnc_createAction;
+[_ccp, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_addActionToObject;
+
+_action = ["rd501_medical_ccp_stitchAll", "Stitch All Patients", "", {
+	params ["_target", "_player", "_params"];
+		[_player, _target, 20] call rd501_fnc_stitchAllWoundsNearbyCCP;
+	}, {_this call rd501_fnc_canStitchNearbyCCP}, {[]}] call ace_interact_menu_fnc_createAction;
+[_ccp, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_addActionToObject;

+ 24 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_deployCCPServer.sqf

@@ -0,0 +1,24 @@
+/*
+ * Author: M3ales
+ *
+ * Replaces the given target object with the CCP object, and adds an ace interact on JIP
+ *
+ * Arguments:
+ * Target Object
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [cursorTarget] call rd501_fnc_deployCCPServer
+ *
+ * Public: No
+ */
+
+params["_target"];
+
+_position = position _target;
+deleteVehicle _target;
+_spawner = rd501_medical_ccp_building createVehicle _position;
+systemChat format["Deployed CCP"];
+
+["rd501_medical_ccp_deployCCPLocal", [_spawner]] call CBA_fnc_globalEventJIP; // raise on all clients (we should be on server)

+ 19 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_deployCcp.sqf

@@ -0,0 +1,19 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Unit
+ * Return Value:
+ * True if eligable to use bandage action
+ *
+ * Example:
+ * [cursorTarget, player, []] call rd501_fnc_canBandageNearbyCCP
+ *
+ * Public: No
+ */
+
+params ["_target", "_player", "_params"];
+
+["rd501_medical_ccp_deployCCPServer", [_target]] call CBA_fnc_serverEvent;
+
+["Deploying CCP Nearby"] call ACE_common_fnc_displayText;

+ 20 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_incrementBandageProgress.sqf

@@ -0,0 +1,20 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Building or object to increment variable on
+ * The player who is performing the action
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [cursorTarget, player] call rd501_fnc_incrementBandageProgress
+ *
+ * Public: No
+ */
+
+params["_origin", "_healer"];
+_progress = _origin getVariable["rd501_medical_ccp_bandageProgress", -1];
+if(_progress >= 0) then {
+	_origin setVariable["rd501_medical_ccp_bandageProgress", _progress + 1, true];
+};

+ 20 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_incrementStitchProgress.sqf

@@ -0,0 +1,20 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Building or object to increment variable on
+ * The player who is performing the action
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [cursorTarget, player] call rd501_fnc_incrementStitchProgress
+ *
+ * Public: No
+ */
+
+params["_origin", "_healer"];
+_progress = _origin getVariable["rd501_medical_ccp_stitchProgress", -1];
+if(_progress >= 0) then {
+	_origin setVariable["rd501_medical_ccp_stitchProgress", _progress + 1, true];
+};

+ 18 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_isDoctor.sqf

@@ -0,0 +1,18 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Player or unit to check
+ * Return Value:
+ * True if they are a doctor (medical level 2+), false otherwise
+ *
+ * Example:
+ * [player] call rd501_fnc_isDoctor
+ *
+ * Public: No
+ */
+
+params["_unit"];
+
+private _class = _unit getVariable ["ace_medical_medicClass", parseNumber (_unit getUnitTrait "medic")];
+_class >= 2

+ 22 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_stitchAllWounds.sqf

@@ -0,0 +1,22 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * The player who is performing the action
+ * The player who is being healed
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [player, player] call rd501_fnc_stitchAllWounds
+ *
+ * Public: No
+ */
+
+params["_healer","_patient"];
+
+private _bandagedWounds = _patient getVariable ["ace_medical_bandagedWounds", []];
+_patient setVariable ["ace_medical_bandagedWounds", [], true];
+_patient setVariable ["ace_medical_stitchedWounds", _bandagedWounds, true];
+
+[_patient] call ace_medical_engine_fnc_updateDamageEffects;

+ 103 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_stitchAllWoundsNearbyCCP.sqf

@@ -0,0 +1,103 @@
+/*
+ * Author: M3ales
+ *
+ * Arguments:
+ * Healer
+ * Origin To Search from
+ * Radius To Search Around for People
+ * Return Value:
+ * Nothing
+ *
+ * Example:
+ * [player, cursorTarget] call rd501_fnc_stitchAllNearbyCCP
+ *
+ * Public: No
+ */
+
+params["_healer", "_origin", "_radius"];
+
+private _nearbyPatients = _origin nearEntities ["CAManBase", _radius] select {
+	[_x] call rd501_fnc_checkInsideCCP &&
+	{
+		count (_x getVariable ["ace_medical_bandagedWounds", []]) > 0
+	}
+};
+
+private _args = [_healer, _nearbyPatients, _origin];
+
+if(count _nearbyPatients == 0) exitWith {
+	["Nobody to Stitch Inside CCP", true, 2, 0] call ace_common_fnc_displayText;
+};
+
+[format["Stitching %1 Patient(s)", count _nearbyPatients], false, 10, 0] call ace_common_fnc_displayText;
+
+private _onFinish = {
+    (_this select 0) params ["_player", "_patients", "_building"];
+	{
+		if([_x] call rd501_fnc_checkInsideCCP) then {
+			[_player, _x] call rd501_fnc_stitchAllWounds;
+		};
+	} forEach (_patients);
+    _building setVariable ["rd501_medical_ccp_stitchProgress", -1, true];
+    _building setVariable["rd501_medical_ccp_stitchMembers", [], true];
+	[_player, "", 1] call ace_common_fnc_doAnimation;
+};
+
+private _onFailure = {
+    params["_args", "_progress", "_errorCode"];
+    _args params["_healer","_nearbyPatients", "_building"];
+    [_healer, "", 1] call ace_common_fnc_doAnimation;
+    _stitchers = _building getVariable ["rd501_medical_ccp_stitchMembers", []];
+    if(count _stitchers <= 1) then {
+        _building setVariable ["rd501_medical_ccp_stitchProgress", -1, true];
+        _building setVariable ["rd501_medical_ccp_stitchMembers", [], true];
+        _building setVariable ["rd501_medical_ccp_stitchProgressComplete", 100];
+    }
+    else
+    {
+        _newArr = _stitchers deleteAt (_stitchers findIf { _x isEqualTo ([] call CBA_fnc_currentUnit)}) select 1;
+        _building setVariable["rd501_medical_ccp_stitchMembers", _newArr, true];
+    }
+};
+
+private _condition = {
+    params["_args", "_progress", "_errorCode"];
+    _args params["_healer","_nearbyPatients", "_building"];
+    if(_progress == -1) exitWith {false};
+    if(_healer getVariable ["ACE_Unconscious", false]) exitWith {false};
+    alive _healer && alive _building
+};
+
+if(_origin getVariable ["rd501_medical_ccp_stitchProgress", -1] == -1) then {
+    private _stitchDuration = ((count _nearbyPatients) * rd501_medical_ccp_stitchDurationSeconds);
+    _origin setVariable ["rd501_medical_ccp_stitchProgress", 0, true];
+    _origin setVariable ["rd501_medical_ccp_stitchMembers", [player], true];
+    _origin setVariable ["rd501_medical_ccp_stitchProgressComplete", _stitchDuration, true];
+}
+else
+{
+    _stitchMembers = _origin getVariable ["rd501_medical_ccp_stitchMembers", []];
+    _stitchMembers append [player];
+    _origin setVariable ["rd501_medical_ccp_stitchMembers", _stitchMembers, true];
+};
+
+[
+    {
+        params ["_args", "_handle"];
+        _args params ["_healer", "_nearbyPatients", "_origin"];
+        _progress = _origin getVariable ["rd501_medical_ccp_stitchProgress", -1];
+        _progressComplete = _origin getVariable ["rd501_medical_ccp_stitchProgressComplete", 100];
+        if(_progress < 0 || _progress >= _progressComplete) exitWith {
+            [_handle] call CBA_fnc_removePerFrameHandler;
+        };
+        if!(_healer getVariable ["ACE_Unconscious", false]) exitWith {
+            ["rd501_medical_ccp_incrementStitch",[_origin, _healer]] call CBA_fnc_serverEvent;
+        };
+    },
+    1,
+    _args
+] call CBA_fnc_addPerFrameHandler;
+
+[_healer, "AinvPknlMstpSnonWnonDr_medic5", 0] call ace_common_fnc_doAnimation;
+
+["rd501_medical_ccp_stitchProgress", "rd501_medical_ccp_stitchProgressComplete",_origin, _args, _onFinish, _onFailure, "Stitching All Patients Inside CCP", _condition] call rd501_fnc_valueProgressBar;

+ 102 - 0
addons - Copy/RD501_Main/functions/medical_ccp/fnc_valueProgressBar.sqf

@@ -0,0 +1,102 @@
+/*
+ * Author: commy2, Glowbal, PabstMirror
+ * Modified by: Mirror
+ * Draw progress bar and execute given function if succesful.
+ * Finish/Failure/Conditional are all passed [_args, _elapsedTime, _totalTime, _errorCode]
+ *
+ * Arguments:
+ * 0: Progress Variable: representation of how complete the bar should be.
+ * 0: Progress Complete Variable: representation of when the bar should be considered 'complete', must be larger than progressVar value.
+ * 1: Arguments, passed to condition, fail and finish <ARRAY>
+ * 2: On Finish: Code called or STRING raised as event. <CODE, STRING>
+ * 3: On Failure: Code called or STRING raised as event. <CODE, STRING>
+ * 4: (Optional) Localized Title <STRING>
+ * 5: Code to check each frame (Optional) <CODE>
+ * 6: Exceptions for checking EFUNC(common,canInteractWith) (Optional)<ARRAY>
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * ["rd501_medical_ccp_stitchProgress", "rd501_medical_ccp_stitchProgressComplete", [], {Hint "Finished!"}, {hint "Failure!"}, "My Title"] call rd501_fnc_valueProgressBar
+ *
+ * Public: Yes
+ */
+
+params ["_progressVar","_progressCompleteVar", "_building", "_args", "_onFinish", "_onFail", ["_localizedTitle", ""], ["_condition", {true}], ["_exceptions", []]];
+
+private _player = ACE_player;
+
+//Open Dialog and set the title
+closeDialog 0;
+createDialog "ace_common_ProgressBar_Dialog";
+
+(uiNamespace getVariable "ace_common_ctrlProgressBarTitle") ctrlSetText _localizedTitle;
+
+//Adjust position based on user setting:
+private _ctrlPos = ctrlPosition (uiNamespace getVariable "ace_common_ctrlProgressBarTitle");
+_ctrlPos set [1, ((0 + 29 * ace_common_settingProgressBarLocation) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2))];
+
+(uiNamespace getVariable "ace_common_ctrlProgressBG") ctrlSetPosition _ctrlPos;
+(uiNamespace getVariable "ace_common_ctrlProgressBG") ctrlCommit 0;
+(uiNamespace getVariable "ace_common_ctrlProgressBar") ctrlSetPosition _ctrlPos;
+(uiNamespace getVariable "ace_common_ctrlProgressBar") ctrlCommit 0;
+(uiNamespace getVariable "ace_common_ctrlProgressBarTitle") ctrlSetPosition _ctrlPos;
+(uiNamespace getVariable "ace_common_ctrlProgressBarTitle") ctrlCommit 0;
+
+[{
+    (_this select 0) params ["_progressVar", "_progressCompleteVar", "_args", "_onFinish", "_onFail", "_condition", "_player", "_building", "_exceptions"];
+
+    private _progress = _building getVariable[_progressVar, -1];
+    private _progressComplete = _building getVariable[_progressCompleteVar, 100];
+    private _errorCode = -1;
+
+    // this does not check: target fell unconscious, target died, target moved inside vehicle / left vehicle, target moved outside of players range, target moves at all.
+    if (isNull (uiNamespace getVariable ["ace_common_ctrlProgressBar", controlNull])) then {
+        _errorCode = 1;
+    } else {
+        if (ACE_player != _player || !alive _player) then {
+            _errorCode = 2;
+        } else {
+            if !([_args, _progress, _errorCode] call _condition) then {
+                _errorCode = 3;
+            } else {
+                if !([_player, objNull, _exceptions] call ace_common_fnc_canInteractWith) then {
+                    _errorCode = 4;
+                } else {
+                    if (_progress >= _progressComplete) then {
+                        _errorCode = 0;
+                    };
+                };
+            };
+        };
+    };
+
+    if (_errorCode != -1) then {
+        //Error or Success, close dialog and remove PFEH
+
+        //Only close dialog if it's the progressBar:
+        if (!isNull (uiNamespace getVariable ["ace_common_ctrlProgressBar", controlNull])) then {
+            closeDialog 0;
+        };
+
+        [_this select 1] call CBA_fnc_removePerFrameHandler;
+
+        if (_errorCode == 0) then {
+            if (_onFinish isEqualType "") then {
+                [_onFinish, [_args, _errorCode]] call CBA_fnc_localEvent;
+            } else {
+                [_args, _errorCode] call _onFinish;
+            };
+        } else {
+            if (_onFail isEqualType "") then {
+                [_onFail, [_args, _progress, _errorCode]] call CBA_fnc_localEvent;
+            } else {
+                [_args, _progress, _errorCode] call _onFail;
+            };
+        };
+    } else {
+        private _progressResult = ((_progress / _progressComplete)) min 1;
+        (uiNamespace getVariable "ace_common_ctrlProgressBar") progressSetPosition _progressResult;
+    };
+}, 0, [_progressVar, _progressCompleteVar, _args, _onFinish, _onFail, _condition, _player, _building, _exceptions]] call CBA_fnc_addPerFrameHandler;

+ 11 - 5
addons - Copy/RD501_Vehicles/land/resupply_box/config.cpp

@@ -77,11 +77,17 @@ class CfgVehicles
 		editorSubcategory = macro_editor_cat(resupply)
 		class TransportItems{};
 		class EventHandlers :DefaultEventhandlers{};
-		class assembleInfo
-		{
-			dissasembleTo[]=
-			{
-				"Land_Medevac_house_V1_F";
+		class ACE_Actions {
+			class ACE_MainActions {
+				displayName = "Deployable CCP";
+				condition = "true";
+				distance = 4;
+				class rd501_deploy_medical_ccp {
+					displayName = "Deploy";
+					statement = "_this call rd501_fnc_deployCCP";
+					icon = "rd501_main\ui_icons\medical_emblem.paa";
+					exceptions[] = {};
+				};
 			};
 		};
 	};