Jump to content
Sign in to follow this  
Grumpy Old Man

Scrambled together a small Salute script

Recommended Posts

Hey folks,

here's a small salute script which I scrambled together from a few already existing scripts and enhanced it a wee bit.

How to use:

1.: Make a new file in your mission folder, called salute.sqf

2.: Copy the code below into the salute.sqf and save the file

3.: Put this into the init field of an unit you wish other units should salute:

nul = [this] execVM "salute.sqf";

salute.sqf

_salutedistance = 7 + (random 2); //how far away the lowerranking has to be to do the initial salute
_resetdistance = 1000; //how far away the higherranking unit has to be until lower ranking units salute him again
_higherranking = _this select 0;
_alreadysaluted = [];

while {alive _higherranking} do {
_salutesleep = 4 + random 3;
_list = position _higherranking nearObjects["Man",_salutedistance];
	_enemysides = side _higherranking call BIS_fnc_enemysides;

{
	if (!(side _x in _enemysides) && {rankId _x < rankId _higherranking} && {!(_x in _alreadysaluted)} && (behaviour _x == "SAFE" OR behaviour _x == "AWARE")) then {

		_x glanceat _higherranking;
		if ((side _x == Civilian) && ((random 50) < 100)) then {
		_civgestures = ["GestureHi","GestureHiB","GestureHiC","GestureNod"];
		_randomgesture = _civgestures select floor random (count _civgestures -1);
		_x playaction _randomgesture;

	} else {
		_x disableAI "ANIM";
		if (primaryWeapon _x == currentWeapon _x) then {
			_x playmove "AmovPercMstpSlowWrflDnon_Salute";
		};

		if (handgunWeapon _x == currentWeapon _x) then {
			_x playmove "AmovPercMstpSrasWpstDnon_Salute";
		};

		if (currentweapon _x == "") then {
			_x action ["Salute",_x];
		};

		_rank = [_x,"DisplayName"] call BIS_fnc_rankParams;
		_messagearray = ["reporting in","reporting for duty","ready for orders","awaiting orders"];
		_message = _messagearray select random (count _messagearray -1);

		if (_x in units group _higherranking) then {
			_x groupchat format ["Sir, %1 %2, %3, Sir!",_rank,name _x,_message];
		};

	};

	_alreadysaluted = _alreadysaluted + [_x];
	_x glanceat objnull;


		if (!(side _x == Civilian)) then {
		_nul = [_x,_salutesleep] spawn {
		_unit = _this select 0;
		_salutesleep = _this select 1;
		_time = time;
		waituntil {time > _time + _salutesleep};
		_unit enableAI "ANIM";
			if (primaryWeapon _unit == currentWeapon _unit) then {
				_unit playmove "AmovPercMstpSlowWrflDnon_SaluteOut";
			};

			if (handgunWeapon _unit == currentWeapon _unit) then {
				_unit playmove "AmovPercMstpSrasWpstDnon_SaluteOut";
			};

			if (currentweapon _unit == "") then {
				_unit playmove "AmovPercMstpSnonWnonDnon_SaluteOut";
			};
			};
		};
	};
} forEach _list;

sleep 0.3;

{
	if ((side _x == side _higherranking) && {_x in _alreadysaluted} && {_x distance _higherranking > 1000}) then {
		_alreadysaluted = _alreadysaluted - [_x];
	};
	sleep 0.1;
} foreach _alreadysaluted;
};

Execute the script on a unit and every unit that's below the executing units rank will salute.

They will only salute once until the distance is above a set value (default 1000m), then they will salute again.

This works similar for civilian units, they will use fitting gestures to greet the executing unit.

Known Issues:

Unarmed units will try to equip their non existant rifle and pistol, salute, go through the non existant weapons again.

Has to be some fault in the animation, gonna take a closer look at that sometime.

Update:

Added a duration for the salute animation, can be defined by the user

The groupchat message will only display if units salute to their own group leaders.

Units will no longer be stuck in the salute animation.

Messages are somewhat randomly chosen.

Units will only salute if in "SAFE" behaviour to avoid saluting in the middle of artillery fire and being surrounded by tanks.

Units will now report for duty if they're in the executing units group.

Edited by Grumpy Old Man
Minor fix

Share this post


Link to post
Share on other sites

VERY cool! Something that BIS should have built into the vanilla game from the very start IMO.

I've got some AI spawns in my mission to help a single player build a group with (group player) createUnit calls. It also uses

_soldier groupChat format ["%2 %1 reporting for duty.", recname, recrank];

to greet the player when they join the group. I would love to have this salute action work as well but not sure how to include the call so it will work since you said "not in the units group will salute"... so I need to find a way to create the unit, then call the salute script, then join the player's group?

While I'm here any idea on how to randomly assign a rank to a createUnit between Private and the player's rank?

Share this post


Link to post
Share on other sites

Thanks!

That works like a treat! I'm still learning scripting and I have a long ways to go. Here is one of my spawn addaction scripts, if you care to take a look:

/////////////////////////////
//Script by [CoFR]October and BASED on:
// [FOCK]ers AI  Recruit
// [FOCK] Mikie J
//////////////////////////////
if (RecruitActive == 0) exitwith {Hint "Recruiting Has been turned off";};

Private ["_soldier","_rankarray","_srankID","_srank","_prankID","_prank","_recname","_pname","_maxp"];

_rankarray=["PRIVATE", "CORPORAL", "SERGEANT", "LIEUTENANT", "CAPTAIN", "MAJOR", "COLONEL"];

_prankID = rankId player;
_pname = name player;
_prank = rank player;
if (player != (leader group player)) exitwith {hint "You must be a Group leader to recruit AI"};

_cnt = count units group player; // returns number of units in player group
_maxp = _prankID + round (_prankID/2);



if(_cnt <=_maxp) then
{

_soldier = (group player) createUnit ["B_mas_usr_Soldier_GL_F_g",(getmarkerpos "rifspawn"),[],0,"NONE"];
//_soldier addUniform "u_b_ghilliesuit";//Add gear here.

_srankID = round random _prankID;
_soldier setUnitRank (_rankarray select _srankID); _recrank = rank _soldier;

_recname = name _soldier;

//hint format ["%2 %1 reporting for duty.", _recname, _recrank];
_soldier groupChat format ["%2 %1 reporting for duty.", _recname, _recrank];
_skillmod = ((skill _soldier) + (_srankID/20) -0.05); _soldier setUnitAbility _skillmod; 


_soldier call compile preprocessFile (TCB_AIS_PATH+"init_ais.sqf");

}

else

{
hint format["%1 %2 you can only have %3 recruits in your immediate command at your rank.", _prank, _pname, _maxp];
};

A couple of questions? In the above script the unit is created on the marker "rifspawn" which I have cleverly hidden inside a barracks. As it is now they spawn onto the marker, take a few steps towards the player, salute, and then finally take the last steps out of the barracks. I would like to find a way to reverse those last two... a way to delay the salute for just a second or two more would have them outside the barracks and in front of the player before saluting. Ideas?

My rank test allows the player to recruit units up to and equal with the player's rank. Spawned units of the same rank as the player do not salute and then, of course, do not use your excellent "reporting for duty" line either. When they are of a lower rank I get both lines, the one from my script and the one from yours. Any ideas on how to clean this up a bit?

Last but not least I'm *trying* to make this mission for COOP with JIP. What's the best way to make sure all the players get this script ran on them?

Thanks in advance!

Share this post


Link to post
Share on other sites

You can either remove the lines from your or from my script,

In the line _list = at the beginning of my script you can adjust the number (7 per default) to your liking, this will increase/decrease the distance at which other units will salute/use gestures.

No Idea about multiplayer scripting (one of my unspoken horrors) but I guess it would work fine if you execute this script on every playable unit.

Share this post


Link to post
Share on other sites

Every once in awhile I get "null" in place of _message. I don't understand the mathematics of _message = _messagearray select random count _messagearray; well enough to know why this might be? Should there be a "floor" or "round" in there somewhere?

Lastly, where did you find the details on BIS_fnc_rankParams? I've googled and checked the wiki but can find no entry on it. Am I missing some secret repository of BIS_fnc_ knowledge somewhere? :P

Edited by Oktyabr

Share this post


Link to post
Share on other sites

The _message error is a minor mistake on my side, fixed it in the first post.

For info on BIS functions just hit Ctrl+F in the editor.

It basically says that the _message is a random selection from the _messagearray. floor means the left side of the array will be chosen more often, ceiling meaning the opposite, if you leave both out it will choose completely randomly without weighting.

Round isn't needed since the count of array elements won't have any decimal numbers (there can't be 0.625 elements in an array).

Edited by Grumpy Old Man

Share this post


Link to post
Share on other sites

Thanks for the tip and the fixes!

Have you given any thought to what I guess would be some sort of event handler to check unit status or environmental conditions to prevent salutes (and civ gestures) during a fire fight? I love the elegant simplicity (again, something BIS should have built into the game from day ONE!) but the beta tester in me is always exploring the boundaries of what's possible. Hence my attempts at making rank affect skill and recruitment efforts as well ;)

---------- Post added at 12:09 PM ---------- Previous post was at 12:06 PM ----------

You can either remove the lines from your or from my script,

In the line _list = at the beginning of my script you can adjust the number (7 per default) to your liking, this will increase/decrease the distance at which other units will salute/use gestures.

I'm still experimenting with the right distance (I can tweak the location of my spawn markers too). As for the multiple greetings I imagine I could either lower the recruitment ranks in my script, so you never recruit anyone of the same rank as player, or get rid of my greeting line entirely and figure out how to adjust your script so recruits of the same rank as player still say something, even without the salute, i.e., "Reporting for duty."

The first solution is obviously the easiest but it means any player who finds himself demoted to private will never be able to recruit even another private to help him complete tasks (start the mission over... all players start as either sergeants or lieutenants, depending on slot) or they should seriously think about just joining an existing group (not scripted yet)... just thinking "out loud" here ;)

Or maybe, change the line in your script

if ((side _x == side _higherranking) && (rankId _x < rankId _higherranking) && !(_x in _alreadysaluted)) then {

to

if ((side _x == side _higherranking) && (rankId _x <= rankId _higherranking) && !(_x in _alreadysaluted)) then {

so units of the same rank also salute?

My question is, since I've never had the privilege of serving IRL myself, I'm not sure how often officers of the same rank might salute each other? Would it look unrealistic to "recruit" a unit of the same rank and they salute player?

Edited by Oktyabr

Share this post


Link to post
Share on other sites

Hmmm... I got things working the way I want (same rank still salutes) but I've got this curious problem. The AI that I use for the addaction has this in it's init:

this setUnitPos ""AUTO""; this disableAI ""MOVE""; this disableAI ""TARGET""; this disableAI ""AUTOTARGET""; this allowdamage false;

for obvious reasons... BUT this AI will salute, which is fine, but gets stuck in that position (saluting). Now I'd like to find a way so they either A) salute and then put their hand back down, B) salute and wait for the player to salute back and THEN put their hand down, or C) find a way of preventing these AI from saluting at all, if they are going to get stuck that way.

Any ideas, anyone?

EDIT --- Looks like I can disable "ANIM" or "FSM" too but then they won't salute. Would be cool if they would salute and put their hand down though, if anyone has an idea of what's going on here... https://community.bistudio.com/wiki/disableAI

Edited by Oktyabr

Share this post


Link to post
Share on other sites

Same ranking units saluting each other might be very situational, I'd take a guess and say that junior officers salute to senior or commanding officers if they're of the same rank.

I added a line that units only salute/gesture each other if they're in safe mode. Did some further testing and if units have Safe behaviour and are getting engaged it can take up to 6 minutes until they go back to safe mode again.

Resolving the stucked AI in the saluting animation could be tricky, I've yet to find a solution for that, using the animation instead of the salute action and checking for unarmed units, units with pistols or units with rifles doesn't seem to work at all, even if I chose the fitting animations depending on the weapon currently equipped by the unit.

Gonna take a closer look at it, units really shouldn't get stuck in the salute animation.

---------- Post added at 09:59 ---------- Previous post was at 08:27 ----------

Upate:

Units should no longer get stuck in the saluting animation.

Known issue added.

Share this post


Link to post
Share on other sites

Update:

Units will no longer be stuck in the salute animation.

Messages are somewhat randomly chosen.

Units will only salute if in "SAFE" behaviour to avoid saluting in the middle of artillery fire and being surrounded by tanks.

Units will now report for duty if they're in the executing units group.

Thanks Grumpy! I must confess that I felt a bit guilty at the realization that I may have inadvertently persuaded you to add the "message" stuff to your script solely to work with my "recruitment" efforts! For that I apologize but I see the last line of your update seems to have repaired that. Didn't mean to cause you more work or to steer your development down a specific path. :)

EDITED-------

Many thanks again! I hope someone from BIS catches wind of this. Rank *should* be used for much more than just deciding who leads a group of AI...

Edited by Oktyabr
per thread author's request

Share this post


Link to post
Share on other sites

Go ahead, I wouldn't mind if you use my script, just use it if you think it fits :D

I primarily made it for a campaign I'm working on and thought I'd share it because it could be useful in a bunch of missions. ;)

I would appreciate it if you could edit your posts and put your scripts in your own thread, that way people will find it when searching for it, feel free to PM me if you have any further questions.

Updated script again:

Units will not report in if the unit they're saluting to isn't their own group leader.

Edited by Grumpy Old Man

Share this post


Link to post
Share on other sites
floor means the left side of the array will be chosen more often, ceiling meaning the opposite, if you leave both out it will choose completely randomly without weighting.

Round isn't needed since the count of array elements won't have any decimal numbers (there can't be 0.625 elements in an array).

I'm afraid this is untrue, and the original objection is valid.

 _selection = _array select floor random count _array;

would be the correct syntax; "random" always returns a floating point value between 0 (inclusive) and the value passed to it (non-inclusive).

Thus, if an array has 4 elements,

_array select random count _array

would end up as

_array select random 4;

which then translates to something like:

_array select 0;
//or
_array select 0.4;
//or 
_array select 3.3;

floor and ceiling commands serve to round down, or up, respectively, to the nearest integer. Thus, in the case of using "count <array>" you should use "floor", so you now get an integer 0,1,2, or 3 (assuming the above example of the array having four elements).

Hopefully this helps somebody at least! :yay:

Share this post


Link to post
Share on other sites

You're right, I always thought it worked the way I described it earlier.

At least it appeared to do so.

Take the randomization of civilian gestures from my script, the "GestureHiC" was only played very rarely, while the "GestureNod" never got played when using the floor command, the ceiling command did the opposite. ;)

When using neither floor or ceiling it always seemed to be perfectly random.

Share this post


Link to post
Share on other sites

Works perfectly, very cool feeling when I walk around Stratis Airbase as the Commander.

Edit: Some ranks won't salute the Col, Major especially. It would also be cool if the salutes could be made a little longer, such as 7secs maybe.

Edited by Strannix
Update

Share this post


Link to post
Share on other sites

Made the salute last for around 6 seconds, duration can be adjusted in one of the first parameters.

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
Sign in to follow this  

×