<commit_before>// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 <EMAIL> *
// ******************************************************************************************
#include "FAR_defines.sqf"

#define FAR_Max_Distance 2.5

////////////////////////////////////////////////
// Player Actions
////////////////////////////////////////////////
FAR_Player_Actions =
{
	if (alive player && player isKindOf "Man") then
	{
		// addAction args: title, filename, (arguments, priority, showWindow, hideOnUse, shortcut, condition, positionInModel, radius, radiusView, showIn3D, available, textDefault, textToolTip)
		{ [player, _x] call fn_addManagedAction } forEach
		[
			["<t color='#FF0000'>" + "Finish off" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_slay"], 101, true, true, "", FAR_Check_Slay],
			["<t color='#00FF00'>" + "Revive" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_revive"], 100, true, true, "", FAR_Check_Revive],
			["<t color='#00FF00'>" + "Stabilize" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_stabilize"], 99, true, true, "", FAR_Check_Stabilize],
			["<t color='#FFFF00'>" + "Drag" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_drag"], 98, true, true, "", FAR_Check_Dragging],
			["<t color='#FFFF00'>" + "Eject injured units from vehicle" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_eject"], 5.2, false, true, "", FAR_Check_Eject_Injured]
		];
	};
}
call mf_compile;

////////////////////////////////////////////////
// Handle Death
////////////////////////////////////////////////
FAR_HandleDamage_EH = "addons\far_revive\FAR_HandleDamage_EH.sqf" call mf_compile;
FAR_fnc_headshotHitPartEH = "addons\far_revive\FAR_headshotHitPartEH.sqf" call mf_compile;

////////////////////////////////////////////////
// Make Player Unconscious
////////////////////////////////////////////////
FAR_Player_Unconscious = "addons\far_revive\FAR_Player_Unconscious.sqf" call mf_compile;

////////////////////////////////////////////////
// Suspect Tracking
////////////////////////////////////////////////
//FAR_setKillerInfo = "addons\far_revive\FAR_setKillerInfo.sqf" call mf_compile; // done from globalCompile.sqf instead, due to use by server

////////////////////////////////////////////////
// Revive Player
////////////////////////////////////////////////
FAR_HandleRevive =
{
	[_this select 0, true] call FAR_HandleTreating;
}
call mf_compile;

////////////////////////////////////////////////
// Stabilize Player
////////////////////////////////////////////////
FAR_HandleStabilize =
{
	[_this select 0, false] call FAR_HandleTreating;
}
call mf_compile;

////////////////////////////////////////////////
// Revive or Stabilize Player
////////////////////////////////////////////////
FAR_HandleTreating =
{
	private "_treatThread";
	_treatThread = _this spawn
	{
		params ["_target", ["_revive",false]]; // _revive false = stabilize
		private "_medicMove";

		if (alive _target) then
		{
			_target setVariable ["FAR_treatedBy", player, true];
			player setVariable ["FAR_isTreating", _target];

			_medicMove = format ["AinvPknlMstpSlayW%1Dnon_medic", [player, true] call getMoveWeapon];
			player playMove _medicMove;

			waitUntil {sleep 0.1; animationState player == _medicMove || !CAN_PERFORM};
			waitUntil {sleep 0.1; animationState player != _medicMove || !CAN_PERFORM};

			if (CAN_PERFORM) then
			{
				if (_revive) then
				{
					_target setVariable ["FAR_isUnconscious", 0, true];
				}
				else
				{
					_target setVariable ["FAR_isStabilized", 1, true];
					_target setVariable ["FAR_handleStabilize", true, true];
				};

				if !("Medikit" in items player) then
				{
					player removeItem "FirstAidKit";
				};
			};

			if (TREATED_BY(_target) == player) then
			{
				_target setVariable ["FAR_treatedBy", nil, true];
			};
		};
	};

	waitUntil {scriptDone _treatThread};
	player setVariable ["FAR_isTreating", nil];
}
call mf_compile;


#define IS_DRAGGING_UNIT(UNIT) (alive player && |UNCONSCIOUS(player) && alive UNIT && UNCONSCIOUS(UNIT) && FAR_isDragging && DRAGGED_BY(UNIT) == player)

////////////////////////////////////////////////
// Drag Injured Player
////////////////////////////////////////////////
FAR_Drag =
{
	if (primaryWeapon player == "") exitWith
	{
		titleText ["You need a primary weapon to be able to drag,\notherwise your player will freeze.\n(Arma 3 bug)", "PLAIN DOWN", 0.5];
	};

	FAR_isDragging = true;

	private ["_target", "_actions"];
	_target = _this select 0;

	player playMoveNow "AcinPknlMstpSrasWrflDnon";

	_target attachTo [player, [0, 1.1, 0.092]];
	_target setDir 180;
	_target setVariable ["FAR_draggedBy", player, true];
	player setVariable ["FAR_isDragging", _target];

	// Rotation fix
	FAR_isDragging_EH = _target;
	publicVariable "FAR_isDragging_EH";

	// Add release action and save its id so it can be removed
	_actions =
	[
		[player, ["<t color='#FFFF00'>" + "Load unit in vehicle" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_load"], 103, true, true, "", FAR_Check_Load_Dragged]] call fn_addManagedAction,
		player addAction ["<t color='#FF0000'>" + "Release" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_release"], 102]
	];

	titleText [format ["Press %1 (%2) if you can't move back.", (actionKeysNamesArray "TactToggle") param [0,"<UNDEFINED>"], actionName "TactToggle"], "PLAIN DOWN", 0.5];
	player selectWeapon primaryWeapon player;

	// Drag & Carry animation fix
	[] spawn
	{
		while {FAR_isDragging} do
		{
			if (vehicle player == player) then
			{
				_animState = animationState player;

				if (_animState == "AcinPknlMstpSrasWrflDnon_AcinPercMrunSrasWrflDnon" || _animState == "helper_switchtocarryrfl") then
				{
					[player, "AcinPknlMstpSrasWrflDnon"] call switchMoveGlobal;
				};

				if (currentWeapon player != primaryWeapon player) then
				{
					player selectWeapon primaryWeapon player;
				};
			};

			sleep 0.5;
		};
	};

	// Wait until release action is used
	waitUntil {!alive player || UNCONSCIOUS(player) || !alive _target || !UNCONSCIOUS(_target) || !FAR_isDragging || isNull DRAGGED_BY(_target)};

	if (!isNull _target) then
	{
		if (!isNull attachedTo _target) then { detach _target };;
		_target setVariable ["FAR_draggedBy", nil, true];
	};

	FAR_isDragging = false;
	player setVariable ["FAR_isDragging", objNull];
	if (vehicle player == player) then { player playMove "AmovPknlMstpSrasWrflDnon" };
	{ [player, _x] call fn_removeManagedAction } forEach _actions;
}
call mf_compile;

FAR_Release =
{
	FAR_isDragging = false;
}
call mf_compile;

FAR_Drag_Load_Vehicle =
{
	params [["_veh",cursorTarget]];
	private "_draggedUnit";
	_draggedUnit = player getVariable ["FAR_isDragging", objNull];

	if (alive player && alive _draggedUnit && attachedTo _draggedUnit == player) then
	{
		FAR_isDragging = false;

		if ([_draggedUnit, _veh, true] call fn_canGetIn) then
		{
			_draggedUnit setVariable ["FAR_cancelAutoEject", true, true];
			detach _draggedUnit;
			[_draggedUnit, _veh, true] call A3W_fnc_getInFast;
		};
	};
}
call mf_compile;

FAR_Eject_Injured =
{
	params [["_veh",cursorTarget]];

	{
		if (UNCONSCIOUS(_x) && [_x, player] call A3W_fnc_isFriendly) then
		{
			moveOut _x;
			unassignVehicle _x;
		};
	} forEach crew _veh;
}
call mf_compile;

FAR_Slay_Target =
{
	private "_target";
	_target = call FAR_FindTarget;

	if ([_target] call FAR_Check_Slay) then
	{
		_target setDamage 1;
		[player, "gutCount", 1] call fn_addScore;
	};
}
call mf_compile;

////////////////////////////////////////////////
// Event handler for public variables
////////////////////////////////////////////////
FAR_public_EH =
{
	if(count _this < 2) exitWith {};

	_EH  = _this select 0;
	_value = _this select 1;

	// FAR_isDragging
	if (_EH == "FAR_isDragging_EH") then
	{
		_value setDir 180;
	};

	// FAR_deathMessage
	if (_EH == "FAR_deathMessage") then
	{
		_names = _value select 0;
		_unitName = _names select 0;
		_killerName = _names param [1, nil];
		_unit = objectFromNetId (_value select 1);
		_killer = objectFromNetId (_value select 2);
		if (alive _unit) then
		{
			switch (true) do<commit_msg>Fixed injured unit hovering on drag release<commit_after>// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.<EMAIL> *
// ******************************************************************************************
#include "FAR_defines.sqf"

#define FAR_Max_Distance 2.5

////////////////////////////////////////////////
// Player Actions
////////////////////////////////////////////////
FAR_Player_Actions =
{
	if (alive player && player isKindOf "Man") then
	{
		// addAction args: title, filename, (arguments, priority, showWindow, hideOnUse, shortcut, condition, positionInModel, radius, radiusView, showIn3D, available, textDefault, textToolTip)
		{ [player, _x] call fn_addManagedAction } forEach
		[
			["<t color='#FF0000'>" + "Finish off" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_slay"], 101, true, true, "", FAR_Check_Slay],
			["<t color='#00FF00'>" + "Revive" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_revive"], 100, true, true, "", FAR_Check_Revive],
			["<t color='#00FF00'>" + "Stabilize" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_stabilize"], 99, true, true, "", FAR_Check_Stabilize],
			["<t color='#FFFF00'>" + "Drag" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_drag"], 98, true, true, "", FAR_Check_Dragging],
			["<t color='#FFFF00'>" + "Eject injured units from vehicle" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_eject"], 5.2, false, true, "", FAR_Check_Eject_Injured]
		];
	};
}
call mf_compile;

////////////////////////////////////////////////
// Handle Death
////////////////////////////////////////////////
FAR_HandleDamage_EH = "addons\far_revive\FAR_HandleDamage_EH.sqf" call mf_compile;
FAR_fnc_headshotHitPartEH = "addons\far_revive\FAR_headshotHitPartEH.sqf" call mf_compile;

////////////////////////////////////////////////
// Make Player Unconscious
////////////////////////////////////////////////
FAR_Player_Unconscious = "addons\far_revive\FAR_Player_Unconscious.sqf" call mf_compile;

////////////////////////////////////////////////
// Suspect Tracking
////////////////////////////////////////////////
//FAR_setKillerInfo = "addons\far_revive\FAR_setKillerInfo.sqf" call mf_compile; // done from globalCompile.sqf instead, due to use by server

////////////////////////////////////////////////
// Revive Player
////////////////////////////////////////////////
FAR_HandleRevive =
{
	[_this select 0, true] call FAR_HandleTreating;
}
call mf_compile;

////////////////////////////////////////////////
// Stabilize Player
////////////////////////////////////////////////
FAR_HandleStabilize =
{
	[_this select 0, false] call FAR_HandleTreating;
}
call mf_compile;

////////////////////////////////////////////////
// Revive or Stabilize Player
////////////////////////////////////////////////
FAR_HandleTreating =
{
	private "_treatThread";
	_treatThread = _this spawn
	{
		params ["_target", ["_revive",false]]; // _revive false = stabilize
		private "_medicMove";

		if (alive _target) then
		{
			_target setVariable ["FAR_treatedBy", player, true];
			player setVariable ["FAR_isTreating", _target];

			_medicMove = format ["AinvPknlMstpSlayW%1Dnon_medic", [player, true] call getMoveWeapon];
			player playMove _medicMove;

			waitUntil {sleep 0.1; animationState player == _medicMove || !CAN_PERFORM};
			waitUntil {sleep 0.1; animationState player != _medicMove || !CAN_PERFORM};

			if (CAN_PERFORM) then
			{
				if (_revive) then
				{
					_target setVariable ["FAR_isUnconscious", 0, true];
				}
				else
				{
					_target setVariable ["FAR_isStabilized", 1, true];
					_target setVariable ["FAR_handleStabilize", true, true];
				};

				if !("Medikit" in items player) then
				{
					player removeItem "FirstAidKit";
				};
			};

			if (TREATED_BY(_target) == player) then
			{
				_target setVariable ["FAR_treatedBy", nil, true];
			};
		};
	};

	waitUntil {scriptDone _treatThread};
	player setVariable ["FAR_isTreating", nil];
}
call mf_compile;


#define IS_DRAGGING_UNIT(UNIT) (alive player && |UNCONSCIOUS(player) && alive UNIT && UNCONSCIOUS(UNIT) && FAR_isDragging && DRAGGED_BY(UNIT) == player)

////////////////////////////////////////////////
// Drag Injured Player
////////////////////////////////////////////////
FAR_Drag =
{
	if (primaryWeapon player == "") exitWith
	{
		titleText ["You need a primary weapon to be able to drag,\notherwise your player will freeze.\n(Arma 3 bug)", "PLAIN DOWN", 0.5];
	};

	FAR_isDragging = true;

	private ["_target", "_actions"];
	_target = _this select 0;

	player playMoveNow "AcinPknlMstpSrasWrflDnon";

	_target attachTo [player, [0, 1.1, 0.092]];
	_target setVariable ["FAR_draggedBy", player, true];
	player setVariable ["FAR_isDragging", _target];

	// Rotation fix
	if (local _target) then
	{
		["FAR_isDragging_EH", _target] call FAR_public_EH;
	}
	else
	{
		FAR_isDragging_EH = _target;
		publicVariable "FAR_isDragging_EH";
	};

	// Add release action and save its id so it can be removed
	_actions =
	[
		[player, ["<t color='#FFFF00'>" + "Load unit in vehicle" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_load"], 103, true, true, "", FAR_Check_Load_Dragged]] call fn_addManagedAction,
		player addAction ["<t color='#FF0000'>" + "Release" + "</t>", "addons\FAR_revive\FAR_handleAction.sqf", ["action_release"], 102]
	];

	titleText [format ["Press %1 (%2) if you can't move back.", (actionKeysNamesArray "TactToggle") param [0,"<UNDEFINED>"], actionName "TactToggle"], "PLAIN DOWN", 0.5];
	player selectWeapon primaryWeapon player;

	// Drag & Carry animation fix
	[] spawn
	{
		while {FAR_isDragging} do
		{
			if (vehicle player == player) then
			{
				_animState = animationState player;

				if (_animState == "AcinPknlMstpSrasWrflDnon_AcinPercMrunSrasWrflDnon" || _animState == "helper_switchtocarryrfl") then
				{
					[player, "AcinPknlMstpSrasWrflDnon"] call switchMoveGlobal;
				};

				if (currentWeapon player != primaryWeapon player) then
				{
					player selectWeapon primaryWeapon player;
				};
			};

			sleep 0.5;
		};
	};

	// Wait until release action is used
	waitUntil {!alive player || UNCONSCIOUS(player) || !alive _target || !UNCONSCIOUS(_target) || !FAR_isDragging || isNull DRAGGED_BY(_target)};

	if (!isNull _target) then
	{
		if (!isNull attachedTo _target) then { detach _target };;
		_target setVariable ["FAR_draggedBy", nil, true];
	};

	FAR_isDragging = false;
	player setVariable ["FAR_isDragging", objNull];
	if (vehicle player == player) then { player playMove "AmovPknlMstpSrasWrflDnon" };
	{ [player, _x] call fn_removeManagedAction } forEach _actions;
}
call mf_compile;

FAR_Release =
{
	FAR_isDragging = false;
}
call mf_compile;

FAR_Drag_Load_Vehicle =
{
	params [["_veh",cursorTarget]];
	private "_draggedUnit";
	_draggedUnit = player getVariable ["FAR_isDragging", objNull];

	if (alive player && alive _draggedUnit && attachedTo _draggedUnit == player) then
	{
		FAR_isDragging = false;

		if ([_draggedUnit, _veh, true] call fn_canGetIn) then
		{
			_draggedUnit setVariable ["FAR_cancelAutoEject", true, true];
			detach _draggedUnit;
			[_draggedUnit, _veh, true] call A3W_fnc_getInFast;
		};
	};
}
call mf_compile;

FAR_Eject_Injured =
{
	params [["_veh",cursorTarget]];

	{
		if (UNCONSCIOUS(_x) && [_x, player] call A3W_fnc_isFriendly) then
		{
			moveOut _x;
			unassignVehicle _x;
		};
	} forEach crew _veh;
}
call mf_compile;

FAR_Slay_Target =
{
	private "_target";
	_target = call FAR_FindTarget;

	if ([_target] call FAR_Check_Slay) then
	{
		_target setDamage 1;
		[player, "gutCount", 1] call fn_addScore;
	};
}
call mf_compile;

////////////////////////////////////////////////
// Event handler for public variables
////////////////////////////////////////////////
FAR_public_EH =
{
	if(count _this < 2) exitWith {};

	_EH  = _this select 0;
	_value = _this select 1;

	// FAR_isDragging
	if (_EH == "FAR_isDragging_EH") then
	{
		if (local _value) then
		{
			_value setDir 180;
			_value spawn // fix for hovering on release
			{
				_unit = _this;
				waitUntil {sleep 0.1; !alive _unit || vehicle _unit != _unit || isNull attachedTo _unit};

				if (alive _unit && vehicle _unit == _unit && isNull attachedTo _unit) then
				{
					_unit setVelocity velocity _unit;
				};
			};
		};
	};

	// FAR_deathMessage
	if (_EH == "FAR_deathMessage") then
	{
		_names = _value select 0;
		_unitName = _names select 0;
		_killerName = _names param [1, nil];
		_unit = objectFromNetId (_value select 1);
		_killer = objectFromNetId (_value select 2);
		if (alive _unit) then
		{
			switch (true) do
{'fraction_non_alphanumeric': 0.24004476908576813, 'fraction_numerical': 0.01095664467483506, 'mean_word_length': 2.797986577181208, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2873187', 'n_tokens_mistral': 6261, 'n_tokens_neox': 5619, 'n_words': 1335}