Jump to content

Recommended Posts

Guys I have this hold action set up to revive downed team mates.

Spoiler

 


params ["_unit"];
private _myOwner = owner _unit;
[
    _unit, 
    "Stabilize Injured", 
    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",  
    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",   
    "(_this distance _target < 4) && (lifeState _target isEqualTO ""INCAPACITATED"") && !(_target getVariable ""underMorphine"")",                                                      
    "_caller distance _target < 4",
    {},
    {hintsilent format ["Stabilization Progress :%1 / 24",_this select 4] }, 
    { 
	params ["_target", "_caller", "_actionId", "_arguments"];
    private _orig_blood = (_target getVariable "unit_bloodTotal");
	private _myOwner = _arguments select 0;
	_caller removeItem "FirstAidKit";
	hint format ["First Aid Kit removed from %1", name _caller];
	_target allowDamage true;
    _target setDamage 0.2;
	0 = [_target, {
		params[ ["_object",objNull,[objNull]] ];
		_object enableAI "ANIM";
		_object setUnconscious false;
		_object setUnitPos "UP";
		_object setCaptive false;
		_object action ["SWITCHWEAPON",_target,_target,0];
	}] remoteExecCall ["bis_fnc_call", _myOwner];
    _target setVariable ["unit_bloodCurrent",_orig_blood,true];
    0 = [_target,"Thanks, I feel fine again!"] remoteExec ["globalChat" ,[0,-2] select isDedicated,false];
    }, 
    {},
    [_myOwner], 
    10,
    1000, 
    false,
    true                                                                        
] remoteExec ["BIS_fnc_holdActionAdd",[0,-2] select isDedicated,_unit];

 

 

 

 

My issues are:

 

1) How can I reduce the completion time if the caller is a medic?

2) Can I cancel the holdAction with a hint if the caller has no FirstAidKits? (I want the hold action to show even if the caller does not have the firsAidKit, I just want the hold action to exit with a hint, would

if ((({""FirstAidKit"" == _x} count (items _caller))<1)) exitWith {hint "You need a firstAidKit";} 

work inside the conditionProgress field?

 

Thank you!

Share this post


Link to post
Share on other sites
1 hour ago, Harzach said:

 

Thank you, I already knew about that but how do I change the 10 seconds to lets say 5 seconds...

Share this post


Link to post
Share on other sites

Maybe two holdActions, one visible to medics only, and vice versa?

 

Share this post


Link to post
Share on other sites
8 hours ago, LSValmont said:

2) Can I cancel the holdAction with a hint if the caller has no FirstAidKits?

Just use the progress condition to check if the player has a FirstAidKit. Then the CODE Interrupt to display the message.

 

8 hours ago, LSValmont said:

1) How can I reduce the completion time if the caller is a medic?

You would need to know the recipients( target of the remoteExec ) getUnitTrait, as per @harzach suggests.

Trouble is you cannot know this from the calling machine( as you are broadcasting to all ) so would need to separate your holdAction off into its own function. Something like...

 

//initPlayerLocal.sqf
TAG_fnc_addStabilizeHoldAction = {
	params[ "_target" ];
	
	[
	    _target, 
	    "Stabilize Injured", 
	    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",  
	    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",   
	    "(_this distance _target < 4)",
	    
	    //Check that _caller has FirstAidKit
	    "_caller distance _target < 4 && { items _caller findIf{ _x == 'FirstAidKit' } > -1 }",
	    
	    //Or even put the check in here at start
	    {},
      
	    {hintSilent format ["Stabilization Progress :%1 / 24",_this select 4] }, 
	    { 
			params ["_target", "_caller", "_actionId", "_arguments"];
		    _caller removeItem "FirstAidKit";
			hint format ["First Aid Kit removed from %1", name _caller];
	    },
	    
	    //If the action is interrupted
	    {
	    	//Was it because they had no FirstAidKit
	    	if ( items _caller findIf{ _x == "FirstAidKit" } isEqualTo -1 ) then {
	    		hint "You need a 'First Aid Kit'";
	    	};
	    },
      
	    [_target], 
	    10 * ( [ 1, 0.75 ] select ( player getUnitTrait "Medic" )), //Medic gets a 25% reduction to time
	    1000, 
	    false,
	    true                                                                        
	] call BIS_fnc_holdActionAdd;
};


//initServer.sqf ( or where ever ) 

[ _target ] remoteExec ["TAG_fnc_addStabilizeHoldAction",[0,-2] select isDedicated];

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
4 minutes ago, Larrow said:

Trouble is you cannot know this from the calling machine

 

Ahhhh. I've been fiddling around for the last hour or so, no wonder I can't get it to work.

Share this post


Link to post
Share on other sites
12 minutes ago, Harzach said:

I've been fiddling around for the last hour or so, no wonder I can't get it to work.

Let me make my comment clear. You can get a remote units trait via getUnitTrait.

It is the fact that the holdAction is being remoteExecuted to all( [ 0, -2 ] select isDedicated ). So if you change the time there in the broadcasted holdAction parameters, everyone would receive the same time. So it needs to changed on each recipients end, hence the reason for separtating the function out rather than calling BIS_fnc_holdActionAdd directly.

  • Thanks 1

Share this post


Link to post
Share on other sites
7 hours ago, Larrow said:

Just use the progress condition to check if the player has a FirstAidKit. Then the CODE Interrupt to display the message.

 

You would need to know the recipients( target of the remoteExec ) getUnitTrait, as per @harzach suggests.

Trouble is you cannot know this from the calling machine( as you are broadcasting to all ) so would need to separate your holdAction off into its own function. Something like...

Spoiler




//initPlayerLocal.sqf
TAG_fnc_addStabilizeHoldAction = {
	params[ "_target" ];
	
	[
	    _target, 
	    "Stabilize Injured", 
	    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",  
	    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",   
	    "(_this distance _target < 4)",
	    
	    //Check that _caller has FirstAidKit
	    "_caller distance _target < 4 && { items _caller findIf{ _x == 'FirstAidKit' } > -1 }",
	    
	    //Or even put the check in here at start
	    {},
      
	    {hintSilent format ["Stabilization Progress :%1 / 24",_this select 4] }, 
	    { 
			params ["_target", "_caller", "_actionId", "_arguments"];
		    _caller removeItem "FirstAidKit";
			hint format ["First Aid Kit removed from %1", name _caller];
	    },
	    
	    //If the action is interrupted
	    {
	    	//Was it because they had no FirstAidKit
	    	if ( items _caller findIf{ _x == "FirstAidKit" } isEqualTo -1 ) then {
	    		hint "You need a 'First Aid Kit'";
	    	};
	    },
      
	    [_target], 
	    10 * ( [ 1, 0.75 ] select ( player getUnitTrait "Medic" )), //Medic gets a 25% reduction to time
	    1000, 
	    false,
	    true                                                                        
	] call BIS_fnc_holdActionAdd;
};


//initServer.sqf ( or where ever ) 

[ _target ] remoteExec ["TAG_fnc_addStabilizeHoldAction",[0,-2] select isDedicated];


 

 

Just WOW!

 

Thank you so much dear @Larrow!

 

Will test this ASAP 😉

Share this post


Link to post
Share on other sites
8 hours ago, Larrow said:

Let me make my comment clear. You can get a remote units trait via getUnitTrait.

It is the fact that the holdAction is being remoteExecuted to all( [ 0, -2 ] select isDedicated ). So if you change the time there in the broadcasted holdAction parameters, everyone would receive the same time. So it needs to changed on each recipients end, hence the reason for separtating the function out rather than calling BIS_fnc_holdActionAdd directly.

 

1) I guess this would be the best approach for me:

 

//initServer.sqf ( or where ever )

{
[ _x ] remoteExec ["TAG_fnc_addStabilizeHoldAction",[0,-2] select isDedicated];
} forEach playableUnits;

2) Won't this also appear for the downed player?

 

3) Your code is not checking if the player is incapacitated, I guess I should re add that?

Share this post


Link to post
Share on other sites
44 minutes ago, LSValmont said:

1) I guess this would be the best approach for me:

Well not particularly like that, I thought originally to suggest this but... the remoteExec Target would need to be changed to _x rather than [ 0 , -2 ] etc. And then you might aswell not use the function and go back to using BIS_fnc_holdActionAdd as your sending a separate broadcast to each player. Plus you have then sent multiple separate messages over the network, rather than just one that all clients react to. If JIP is included you then have multiple messages sitting in the queue etc etc

 

50 minutes ago, LSValmont said:

2) Won't this also appear for the downed player?

Yes but so would your original. You could always add to the top of the function that if the player( local client on receiving machine ) is the _target( unit action is added to ) then exit the script.

 

52 minutes ago, LSValmont said:

3) Your code is not checking if the player is incapacitated, I guess I should re add that?

Yes add back in all your stuff, I just removed all the unessecary bits for testing.

Share this post


Link to post
Share on other sites
1 hour ago, Larrow said:

Well not particularly like that, I thought originally to suggest this but... the remoteExec Target would need to be changed to _x rather than [ 0 , -2 ] etc. And then you might aswell not use the function and go back to using BIS_fnc_holdActionAdd as your sending a separate broadcast to each player. Plus you have then sent multiple separate messages over the network, rather than just one that all clients react to. If JIP is included you then have multiple messages sitting in the queue etc etc

 

Yes but so would your original. You could always add to the top of the function that if the player( local client on receiving machine ) is the _target( unit action is added to ) then exit the script.

 

Yes add back in all your stuff, I just removed all the unessecary bits for testing.

 

Allright can I give you the whole scope of it?

 

What I made is basically a custom system where players get two variables to represent their "HEALTH" status, one is "BLOOD" and the other is the default arma damage that I call on the UI "WOUNDS".

 

Basically your BLOOD goes down while your WOUNDS go up.

 

If your wounds are 35% or more you start bleeding.

If your BLOOD reaches 0 you die.

 

At 20% BLOOD you go unconscious. (Your wounds, AKA "damage player", can never go above 70%) so you can only really die by loosing all your blood and not by getting too many wounds.

 

Unconscious players can be revived by other players or by themselves if they have First Aid Kits on them (But the self bandage progress takes more time than being healed by another player).

 

When players heal their WOUNDS below 35% they start regaining BLOOD slowly. (That promotes revived/healed players not to rush back again into the action so soon after being incapacitated, they now have to wait for their BLOOD to go up again or face potential instant incapacitation on even the smallest wound).

 

So, low BLOOD makes you go INCAPACITATED or DEAD but WOUNDS make you loose BLOOD. It is quite logical I believe.

 

Here is the whole Script:

Spoiler

 


vMedical = {
params [["_unit",objNull,[objNull]],["_maxBlood_unit",100,[100]],["_bloodPacks_unit",99,[99]],["_morphineTime_unit",20,[0]]];
if (!isNil {_unit getVariable "bloodHandleDamage"}) exitWith {hint "Unit already has bloodHandleDamage"};
_unit setVariable ["bloodHandleDamage",true,true];

private _bloodStart_unit = _maxBlood_unit/100;

_unit setVariable ["unit_bloodTotal",_bloodStart_unit,true];
_unit setVariable ["unit_bloodCurrent",_bloodStart_unit,true];
_unit setVariable ["bloodPacks_unit",_bloodPacks_unit,true];
_unit setVariable ["morphineTime_unit",_morphineTime_unit,true];
_unit setVariable ["underMorphine",false];
_unit setVariable ["fallDamaged",nil];
_unit removeAllEventHandlers "HandleDamage";

_unit addEventhandler ["HandleDamage",vBloodDamageEH]; // Give players the custom Damage EH
_unit spawn selfMedicalHA; // Give players the option to heal themselves.
_unit spawn othersMedicalHA; // Give players the option for other players to heal them.
};

//default ammount = 5000;
vbloodEffect = {
params ["_unit", "_ammount"];
if (isPlayer _unit && local _unit) then {[_ammount] call BIS_fnc_bloodEffect};
if (random 10>7) then {[_unit] call vPainShout;};
};

vBloodDamageEH = {
params ["_unit", "_selection", "_damage", "_source", "_projectile", "_hitIndex", "_instigator", "_hitPoint"];

if (_projectile isEqualTo "") then {
private _origDamage = if (_selection isEqualTo "") then {damage _unit} else {_unit getHit _selection};
private _addedDamage = _damage - _origDamage;
private _addedCoef = 0.9;
private _finalAdded = _addedDamage * _addedCoef;
private _finalDamage = _origDamage + _finalAdded;

	switch (alive _unit && (!(lifeState _unit isEqualTo "INCAPACITATED"))) do {
		case (_finalDamage > 0.20 && _finalDamage < 0.70): {
			if (!isNil {_unit getVariable "fallDamaged"}) exitWith { if (vDebug) then {hint "Preventing Fall Damage Spam"}; };
			[_unit,5000] call vbloodEffect;
			[{playSound3D ["A3\Missions_F_Bootcamp\data\sounds\surrender_fall.wss", _unit];},[],0.10] call CBA_fnc_waitAndExecute;
			_unit setVariable ["fallDamaged",true];
			_unit setUnconscious true;
			private _rdmLegDam = selectRandom [0.1,0.2,0.3,0.4,0.5];
			private _legDmgCheck = _unit getHitPointDamage "hitLegs";
			private _legDamage =  _legDmgCheck + _rdmLegDam;
			_unit setHitPointDamage ["hitLegs", _legDamage];
			private _unitCurrDmg = damage _unit;
			private _rdmDam = selectRandom [0.05,0.1,0.15];
			_unit setDamage (_unitCurrDmg + _rdmDam);
			private _bloodLoss = selectRandom [0.05,0.1,0.15];
			private _currBlood = _unit getVariable "unit_bloodCurrent";
			private _finalBlood = _currBlood - _bloodLoss;
			_unit setVariable ["unit_bloodCurrent",_finalBlood,true];
			[
				{
				params ["_unit"];
				_unit setUnconscious false;
				_unit setCaptive false;
				_unit setUnitPos "UP";
				_unit action ["SWITCHWEAPON",_unit,_unit,0];
				_unit setVariable ["fallDamaged",nil];
				},
				[_unit],
				(4 + (random 8))
			] call CBA_fnc_waitAndExecute;
		};
		case (_finalDamage > 0.70): {
			if (!isNil {_unit getVariable "fallDamaged"}) exitWith { if (vDebug) then {hint "Preventing Fall Damage Spam"}; };
			[_unit,10000] call vbloodEffect;
			[{playSound3D ["A3\Missions_F_EPA\data\sounds\combat_deafness.wss", _unit];},[],0.10] call CBA_fnc_waitAndExecute;
			_unit setVariable ["fallDamaged",true];
			_unit setUnconscious true;
			private _rdmLegDam = selectRandom [0.4,0.5,0.6,0.7,0.8];
			private _legDmgCheck = _unit getHitPointDamage "hitLegs";
			private _legDamage =  _legDmgCheck + _rdmLegDam;
			_unit setHitPointDamage ["hitLegs", _legDamage];
			private _unitCurrDmg = damage _unit;
			private _rdmDam = selectRandom [0.15,0.2,0.25];
			_unit setDamage (_unitCurrDmg + _rdmDam);
			private _bloodLoss = selectRandom [0.1,0.15,0.2];
			private _currBlood = _unit getVariable "unit_bloodCurrent";
			private _finalBlood = _currBlood - _bloodLoss;
			_unit setVariable ["unit_bloodCurrent",_finalBlood,true];
			[
				{
				params ["_unit"];
				_unit setUnconscious false;
				_unit setCaptive false;
				_unit setUnitPos "UP";
				_unit action ["SWITCHWEAPON",_unit,_unit,0];
				_unit setVariable ["fallDamaged",nil];
				},
				[_unit],
				(6 + (random 10))
			] call CBA_fnc_waitAndExecute;
		};
		default {};
	};
false
} else {

_origDamage = 0; _addedDamage = 0; _finalDamage = 0; _headMultiplier = 1; _neckMultiplier = 1; _bodyMultiplier = 1; _legsMultiplier = 1; _handsMultiplier = 1; _overAllMultiplier = 1;

if (_addedDamage > 0.05) then {[_unit,5000] call vbloodEffect;};

if ( (_projectile) find  "buck" >= 0 or (_projectile) find  "Pellet" >= 0) then {_headMultiplier = 1; _neckMultiplier = 0.04; _bodyMultiplier = 0.04; _legsMultiplier = 0.01; _handsMultiplier = 0.01; _overAllMultiplier = 0.03;};

switch (true) do {
case (_selection isEqualTo "face_hub"): {_origDamage = _unit getHitPointDamage "hitface"; _addedDamage = (_damage - _origDamage)*_headMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "neck"): {_origDamage = _unit getHitPointDamage "hitneck"; _addedDamage = (_damage - _origDamage)*_neckMultiplier; _finalDamage = _origDamage + _addedDamage;};			
case (_selection isEqualTo "head"): {_origDamage = _unit getHitPointDamage "hithead"; _addedDamage = (_damage - _origDamage)*_headMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "pelvis"): {_origDamage = _unit getHitPointDamage "hitpelvis"; _addedDamage = (_damage - _origDamage)*_bodyMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "spine1"): {_origDamage = _unit getHitPointDamage "hitabdomen"; _addedDamage = (_damage - _origDamage)*_bodyMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "spine2"): {_origDamage = _unit getHitPointDamage "hitdiaphragm"; _addedDamage = (_damage - _origDamage)*_bodyMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "spine3"): {_origDamage = _unit getHitPointDamage "hitchest"; _addedDamage = (_damage - _origDamage)*_bodyMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "body"): {_origDamage = _unit getHitPointDamage "hitbody"; _addedDamage = (_damage - _origDamage)*_bodyMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "arms"): {_origDamage = _unit getHitPointDamage "hitarms"; _addedDamage = (_damage - _origDamage)*_handsMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "hands"): {_origDamage = _unit getHitPointDamage "hithands"; _addedDamage = (_damage - _origDamage)*_handsMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "legs"): {_origDamage = _unit getHitPointDamage "hitlegs"; _addedDamage = (_damage - _origDamage)*_legsMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo ""): {_origDamage = damage _unit; _addedDamage = (_damage - _origDamage)*_overAllMultiplier; _finalDamage = _origDamage + _addedDamage;};
case (_selection isEqualTo "incapacitated"): {_origDamage = damage _unit; _finalDamage = _origDamage;};
default {};
};

	private _damCoef = 0.9;
	_finalDamage = _finalDamage*_damCoef;

	hint format ["Final %1 Added %2 selection %3 Original %4", _finalDamage, _addedDamage, _selection, _origDamage];

	// private _totalBlood = (_unit getVariable "unit_bloodTotal");
	private _cur_blood 	= (_unit getVariable "unit_bloodCurrent");
	private _vbloodLoss = _finalDamage * (0.05 + (random 0.05));
	if (damage _unit > 0.55) then {_vbloodLoss = _vbloodLoss * 1.1;};
	_newBlood = _cur_blood - _vbloodLoss;
	if (_newBlood > 0.2) then {_unit setVariable ["unit_bloodCurrent",_newBlood,true]; [_unit,5000] call vbloodEffect;} else {_unit setVariable ["unit_bloodCurrent",0.19,true];};
	if (_finalDamage < 0.70) then {
	_finalDamage
	} else {
	_finalDamage = 0.71;
	_unit setHitPointDamage ["hitLegs", 0.9];
	_finalDamage
	};

};

};

selfMedicalHA = {
params ["_unit"];
private _myOwner = owner _unit;
[
    _unit, 
    "Bandage yourself and Apply Morphine", 
    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",  
    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",   
    "(lifeState _target isEqualTo ""INCAPACITATED"") && (_this isEqualTo player) && isNil{_target getVariable ""fallDamaged""} && !(_target getVariable ""underMorphine"") && (({""FirstAidKit"" == _x} count (items _target))>0)",                                                      
    "(lifeState _target isEqualTo ""INCAPACITATED"")",
    {},
    {hintsilent format ["Bandaging Progress :%1 / 24",_this select 4] }, 
    {
		params ["_target", "_caller", "_actionId", "_arguments"];
		private _myOwner = _arguments select 0;
		0 = [_target,"Wounds Bandaged, now I must wait for the morphine to kick in!"] remoteExec ["globalChat" ,[0,-2] select isDedicated,false];
		_target allowDamage true;
		_target setDamage 0.55;
		_target setVariable ["underMorphine",true];
		_downtime_seconds = (_target getVariable "morphineTime_unit");
		hint format ["%1 Applied a Morphine Shot to himself!", name _target];
		["Wait for the Morphine to take effect or press ESC to respawn.", _downtime_seconds, {alive _object}, 
		{
		params ["_target"];
		hint "Morphine Done";
		player setVariable ["unit_bloodCurrent",0.40,true];
		player enableAI "ANIM";
		player setUnconscious false;
		player setUnitPos "UP";
		player setCaptive false;
		player action ["SWITCHWEAPON",player,player,0];
		player setVariable ["underMorphine",false];
		player removeItem "FirstAidKit";
		hint format ["First Aid Kit removed from %1", name player];	
		},
		{
		params ["_target"];
		hint "morphine Aborted";
		player setDamage 1;
		},
		{
		[_target]
		}
		] call CBA_fnc_progressBar;
    },
    {}, 
    [_myOwner], 
    12,
    1000, 
    false,
    true                                                                        
] remoteExec ["BIS_fnc_holdActionAdd",[0,-2] select isDedicated,_unit];
};

othersMedicalHA = {
params ["_unit"];
private _myOwner = owner _unit;
[
    _unit, 
    "Stabilize Injured", 
    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",  
    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",   
    "(_this distance _target < 4) && (lifeState _target isEqualTO ""INCAPACITATED"") && !(_target getVariable ""underMorphine"")",                                                      
    "_caller distance _target < 4",
    {},
    {hintsilent format ["Stabilization Progress :%1 / 24",_this select 4] }, 
    { 
	params ["_target", "_caller", "_actionId", "_arguments"];
    private _orig_blood = (_target getVariable "unit_bloodTotal");
	private _myOwner = _arguments select 0;
	_caller removeItem "FirstAidKit";
	hint format ["First Aid Kit removed from %1", name _caller];
	_target allowDamage true;
    _target setDamage 0.2;
	0 = [_target, {
		params[ ["_object",objNull,[objNull]] ];
		_object enableAI "ANIM";
		_object setUnconscious false;
		_object setUnitPos "UP";
		_object setCaptive false;
		_object action ["SWITCHWEAPON",_target,_target,0];
	}] remoteExecCall ["bis_fnc_call", _myOwner];
    _target setVariable ["unit_bloodCurrent",_orig_blood,true];
    0 = [_target,"Thanks, I feel fine again!"] remoteExec ["globalChat" ,[0,-2] select isDedicated,false];
    }, 
    {},
    [_myOwner], 
    10,
    1000, 
    false,
    true                                                                        
] remoteExec ["BIS_fnc_holdActionAdd",[0,-2] select isDedicated,_unit];
};

TAG_fnc_addStabilizeHoldAction = {
	params[ "_target" ];
	[
	    _target, 
	    "Stabilize Injured", 
	    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",  
	    "\a3\ui_f\data\IGUI\Cfg\holdactions\holdAction_reviveMedic_ca.paa",   
	    "(_this distance _target < 4)",
	    
	    //Check that _caller has FirstAidKit
	    "_caller distance _target < 4 && { items _caller findIf{ _x == 'FirstAidKit' } > -1 }",
	    
	    //Or even put the check in here at start
	    {},
      
	    {hintSilent format ["Stabilization Progress :%1 / 24",_this select 4] }, 
	    { 
			params ["_target", "_caller", "_actionId", "_arguments"];
		    _caller removeItem "FirstAidKit";
			hint format ["First Aid Kit removed from %1", name _caller];
			
			_target allowDamage true;
			_target setDamage 0.2;
			_target enableAI "ANIM";
			_target setUnconscious false;
			_target setCaptive false;
			_target setUnitPos "UP";
			_target action ["SWITCHWEAPON",_target,_target,0];
			private _orig_blood = (_target getVariable "unit_bloodTotal");
			_target setVariable ["unit_bloodCurrent",_orig_blood,true];
			
	    },
	    
	    //If the action is interrupted
	    {
	    	//Was it because they had no FirstAidKit
	    	if ( items _caller findIf{ _x == "FirstAidKit" } isEqualTo -1 ) then {
	    		hint "You need a 'First Aid Kit'";
	    	};
	    },
      
	    [_target], 
	    10 * ( [ 1, 0.75 ] select ( player getUnitTrait "Medic" )), //Medic gets a 25% reduction to time
	    1000, 
	    false,
	    true                                                                        
	] call BIS_fnc_holdActionAdd;
};

/*

Previous function called from:
//initServer.sqf by using:
	{
		[ _x ] remoteExec ["TAG_fnc_addStabilizeHoldAction",[0,-2] select isDedicated];
	} forEach playableUnits;

*/

 

 

 

 

All that wall of code just so you can understand what I am going after... it is quite complex but also understandable I believe. (I HOPE)

 

And this is the code that loops on PLAYERS to complete the BLOOD system and another systems like my custom STEALTH/UNDERCOVER system:
 

Spoiler

 


playerhasCompass = false;

woundedSoundsLong = [ 
"A3\Missions_F_EPA\data\sounds\WoundedGuyA_01.wss", 
"A3\Missions_F_EPA\data\sounds\WoundedGuyA_02.wss", 
"A3\Missions_F_EPA\data\sounds\WoundedGuyA_03.wss", 
"A3\Missions_F_EPA\data\sounds\WoundedGuyA_04.wss", 
"A3\Missions_F_EPA\data\sounds\WoundedGuyA_05.wss", 
"A3\Missions_F_EPA\data\sounds\WoundedGuyA_06.wss", 
"A3\Missions_F_EPA\data\sounds\WoundedGuyA_07.wss", 
"A3\Missions_F_EPA\data\sounds\WoundedGuyA_08.wss" 
];

vPlayablesLoop = {
params ["_unit"];

//no loop should last forever
if!(alive _unit) exitWith {};
// Prevent Errors if Stealth is not Ready/Present
if (isNil "fullUndercover") then {fullUndercover = false;};

if (isPlayer _unit) then {
	if !(canTriggerDynamicSimulation _unit) then {_unit triggerDynamicSimulation true;};
};

if ("Compass" in (items player)) then {playerhasCompass = true;} else {playerhasCompass = false;};

if (damage _unit > 0.45 && damage _unit < 1) then {
	private _bloodLoss = selectRandom [damage _unit * 0.01,damage _unit * 0.02,damage _unit * 0.03];
	if (damage _unit > 0.68 && damage _unit < 1) then {_bloodLoss = selectRandom [damage _unit * 0.01,damage _unit * 0.02,damage _unit * 0.03]};
	private _currBlood = _unit getVariable "unit_bloodCurrent";
	if (_currBlood < 0.21) then {_bloodLoss = selectRandom [0.001,0.002];};
	if (_unit getVariable "underMorphine") then {_bloodLoss = 0;};
	private _finalBlood = _currBlood - _bloodLoss;
	_unit setVariable ["unit_bloodCurrent",_finalBlood,true];
	if ((_unit getVariable "unit_bloodCurrent" < 0.20) && !(lifeState _unit isEqualTo "INCAPACITATED")) then {
		_unit allowDamage false;
		_unit setUnconscious true;
		_unit setCaptive true;
		_unit setDamage 0.70;
		_unit setVariable ["unit_bloodCurrent",0.19,true];
		[_unit,"I am down! Need help!"] remoteExec ["globalChat" ,0];
		_bloodPacksLeft = _unit getVariable "bloodPacks_unit";
		_bloodPacks_left = _bloodPacks_left - 1; _unit setVariable ["bloodPacks_unit",_bloodPacks_left,true];
		private _inVehicle = !(isNull objectParent _unit);
		if (_inVehicle) then {unassignvehicle _unit; moveout _unit; _unit action ["eject", (vehicle _unit)];};
	};
	if ((_unit getVariable "unit_bloodCurrent" < 0.01) && (lifeState _unit isEqualTo "INCAPACITATED")) then {_unit allowDamage true; _unit setDamage 1;};
	titleText ["Your wounds are significant and you are bleeding, use a first aid kit to bandage yourself ASAP!","PLAIN DOWN"]; titleFadeOut 12;
	private _bloodEffectIntensity = (damage _unit * 13000);
	[_unit,_bloodEffectIntensity] call vbloodEffect;
	if (random 10>8) then { [{playSound3D [selectRandom woundedSoundsLong, player];},[],0.10] call CBA_fnc_waitAndExecute; };
};

if (damage _unit < 0.35 && damage _unit > 0 /*&& _hydration > 55 && _nutrition > 55*/) then {
	_unit setDamage (damage _unit - 0.005);
	if (damage _unit > 0.1) then {
	titleText ["Your wounds are healing, take cover...","PLAIN DOWN"]; titleFadeOut 6;
	};
};

if ((_unit getVariable "unit_bloodCurrent" > 0) && (_unit getVariable "unit_bloodCurrent" < 1) && damage _unit < 0.25 && !(lifeState _unit isEqualTo "INCAPACITATED") /*&& _hydration > 55 && _nutrition > 55*/) then {
	_bloodGain = selectRandom [0.01,0.015,0.02];
	_currBlood = _unit getVariable "unit_bloodCurrent";
	_finalBloodGain = _currBlood + _bloodGain;
	_unit setVariable ["unit_bloodCurrent",_finalBloodGain,true];
	titleText ["Your wounds are minor and you are regaining blood...","PLAIN DOWN"]; titleFadeOut 6;
};

// Part of the new Stealth System.
switch (alive _unit && (!(lifeState _unit isEqualTo "INCAPACITATED"))) do {
	case (stance _unit isEqualTo "STAND"): {
	_unit setUnitTrait ["camouflageCoef",0.8];
	_unit setUnitTrait ["audibleCoef", 0.8];
	_unit setUnitTrait ['loadCoef',0.8];
	_unit setCustomAimCoef 0.50;
	_unit setUnitRecoilCoefficient 0.60;
	_unit setAnimSpeedCoef 1.10;
	};
	case (stance _unit isEqualTo "CROUCH"): {
	_unit setUnitTrait ["camouflageCoef",0.6];
	_unit setUnitTrait ["audibleCoef", 0.6];
	_unit setUnitTrait ['loadCoef',0.6];
	_unit setCustomAimCoef 0.40;
	_unit setUnitRecoilCoefficient 0.50;
	};
	case (stance _unit isEqualTo "PRONE"): {
	_unit setUnitTrait ["camouflageCoef",0.4];
	_unit setUnitTrait ["audibleCoef", 0.4];
	_unit setUnitTrait ['loadCoef',0.4];
	_unit setCustomAimCoef 0.30;
	_unit setUnitRecoilCoefficient 0.40;
	};
	case (stance _unit isEqualTo "UNDEFINED"): {
	_unit setUnitTrait ["camouflageCoef",0.2];
	_unit setUnitTrait ["audibleCoef", 0.2];
	_unit setUnitTrait ['loadCoef',0.2];
	_unit setCustomAimCoef 0.60;
	_unit setUnitRecoilCoefficient 0.70;
	};
	default {};
};

if (!isNil "vStealthEnabled") then {
	// Undercover Check
	if (captive _unit) then {
		private _inVehicle = !(isNull objectParent _unit);
		private _inCivVehicle = typeOf(vehicle _unit) in civVehicles;
		if (_inVehicle && !_inCivVehicle) then {
			_unit setCaptive false;
			[_unit,false] remoteExec ["setCaptive", 0];
			systemchat "You have been compromised by your Vehicle!";
			["Undercover: OFF",0,0,5,0,0] spawn bis_fnc_dynamicText;
			if (random 10>8) then {[player,selectRandom ["going","stayalert","getready","onthemove","nosir","motherf","sonof","fuck","closethatdoor"]] call vPlaySounds;};			
		} else {
			private _noWeapon = currentWeapon _unit isEqualTo "";
			private _enemySides = [side group _unit] call BIS_fnc_enemySides;
			private _looksLikeCiv = uniform _unit in civUniforms;
			private _sideOfUniform = _unit call vCheckUniform;
			private _looksLikeEnemy = _sideOfUniform in _enemySides;
			private _modedCivUniform = _sideOfUniform isEqualTo CIVILIAN;
			
			if (fullUndercover && (!(lifeState _unit isEqualTo "INCAPACITATED"))) then {
			//if !(_noWeapon) then {fullUndercover = false; systemchat "You no longer look like a Civilian (Weapon)";};
			private _fullUndercoverDetRange = 10^2;
			if !(_noWeapon) then {_fullUndercoverDetRange = 50^2;};
			private _noEnemyKnowsMeFull = ((allGroups findIf {side _x in _enemySides && { (leader _x distanceSqr _unit) < _fullUndercoverDetRange } && { (leader _x knowsAbout _unit >= 2) } }) isEqualTo -1);
			if (!_noEnemyKnowsMeFull) then {
				_unit setCaptive false;
				[_unit,false] remoteExec ["setCaptive", 0];
				systemchat "You came to close to an enemy, your full cover is blown!";
				["Undercover: OFF",0,0,5,0,0] spawn bis_fnc_dynamicText;
				if (random 10>8) then {[player,selectRandom ["targetonsight","stayalert","getready","staysharp","getsettoengage","danger","enemydetected","enemycontact","eyesontarget"]] call vPlaySounds;};
			};			
				switch (!_inCivVehicle) do {
					case (!_looksLikeCiv && !_looksLikeEnemy && !_modedCivUniform): {fullUndercover = false; systemchat "You no longer look like a Civilian (Uniform)";};
					//case (!_noWeapon): {fullUndercover = false; systemchat "You no longer look like a Civilian (weapon)";};
					default {};
				};
			};
			if (!fullUndercover) then {
				if (!(lifeState _unit isEqualTo "INCAPACITATED")) then {
					if (_noWeapon) then {
						private _stealthRangeClose = 80^2;
						private _noEnemyKnowsMeClose = ((allGroups findIf {side _x in _enemySides && { (leader _x distanceSqr _unit) < _stealthRangeClose } && { (leader _x knowsAbout _unit >= 2) } }) isEqualTo -1);	
						if (!_noEnemyKnowsMeClose) then {
							_unit setCaptive false;
							[_unit,false] remoteExec ["setCaptive", 0];
							systemchat "Enemies close, you have been compromised!";
							["Undercover: OFF",0,0,5,0,0] spawn bis_fnc_dynamicText;
							if (random 10>8) then {[player,selectRandom ["targetonsight","stayalert","getready","staysharp","getsettoengage","danger","enemydetected","enemycontact","eyesontarget"]] call vPlaySounds;};
						};
					} else {
						private _stealthRange = 180^2;
						private _noEnemyKnowsMe = ((allGroups findIf {side _x in _enemySides && { (leader _x distanceSqr _unit) < _stealthRange } && { (leader _x knowsAbout _unit >= 2) } }) isEqualTo -1);
						if (!_noEnemyKnowsMe) then {
							_unit setCaptive false;
							[_unit,false] remoteExec ["setCaptive", 0];
							systemchat "You have been compromised by your weapon!";
							["Undercover: OFF",0,0,5,0,0] spawn bis_fnc_dynamicText;
							if (random 10>8) then {[player,selectRandom ["targetonsight","stayalert","getready","staysharp","getsettoengage","danger","enemydetected","enemycontact","eyesontarget"]] call vPlaySounds;};
						};
					};
				};
			};
		};	
	};
};

// loop	
[
	vPlayablesLoop,
	_unit,
	4
] call CBA_fnc_waitAndExecute;
};

 

 

 

 

Again, sorry for the wall of code....

 

This is for a 12 player mission I am making in the veins of Hunter 6 but slightly less hardcore... Players do get only one life so that is why I am so forgiving in terms of the options they have for healing and also their Blood Regeneration when they are low on wounds...

 

Perhaps it is better if I upload the whole mission for you?

10MB, no mods required other than CBA

  • Like 1

Share this post


Link to post
Share on other sites
15 hours ago, LSValmont said:

Perhaps it is better if I upload the whole mission for you?

You can do. Would be handy to see the whole process, and where everything is actually being called from.

Still in the process of trying to take everything in.

Share this post


Link to post
Share on other sites
5 hours ago, Larrow said:

You can do. Would be handy to see the whole process, and where everything is actually being called from.

Still in the process of trying to take everything in.

 

Thank you! Here is the mission folder: https://drive.google.com/open?id=1477sHdr2I7R9paj9QcYRlQO9b1JJdlJm

 

Host it in MP

 

Sorry about the overwhelming info and code!

 

Not in a hurry so take your time, having an adviser such as yourself is a privilege!

 

Also just change anything you want on the mission and when you re upload I will check it out and learn from there... because posting everything here on the forums could be tedious.

 

PS: When on the mission you can press "F" to access a custom script based ACE like menu that I made mainly to move my Ai squad around better but quickly expanded into a lot more but it is only 70% done.

PS2: That "F" menu has the option to recruit Ai units you are looking at.

PS3: In order to go undercover you need to holster your weapon by pressing "H".

PS4: When playing the mission you should pick the last unit on the list (Hunter01: John "Big Boss" Sheridan) as he is the only team member who can steal civ uniforms and go full undercover, the others can only go partial undercover).

Share this post


Link to post
Share on other sites

The uploaded mission might have a dependency on the OLD MAN workshop version @Larrow, if so just remove "A3_Missions_F_Oldman" from the mission file.

Share this post


Link to post
Share on other sites

Cool I've downloaded and will have a look over it. Wont be today, not feeling to good.

  • Thanks 1

Share this post


Link to post
Share on other sites
4 hours ago, Larrow said:

Cool I've downloaded and will have a look over it. Wont be today, not feeling to good.

 

Hey! Health comes before anything as the pandemic has shown, so take care and rest, disconnect a couple days if you can.

 

In the mean time I will work on the UI side of the mission 😉

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×