Jump to content
pierremgi

displaying successive hints

Recommended Posts

Hi all and happy new year,

I probably missed some topic about my aim. I need (MP scenario) to display some hints to players. I don't have problem to remote execute that but the fact is these hints are spawned depending on some success or phases of the scenario. My problem is that the hints crushed them and sometimes there is no duration between them, so the information is lost.

There is no command or function detecting if a hint is displayed (or perhaps a control?). So, it's difficult to manage a kind of queue (the exact time for starting a hint has less importance than the information). I'm looking for a code able to queue some texts (queue must be adaptable, not fixed in advance) and displays them as 10 sec. per hint, as required, all game long.

All ideas are welcome!

Share this post


Link to post
Share on other sites

You could put the messages in array and then get the first element from the array and display it 10 seconds and then delete it from array, then get next message from array and so on (the array would be in client)

  • Like 1

Share this post


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

Rather than trying to hack IGUI why not write custom hint

this.

 

All it needs for the hint system to break is some 3rd party script/mod to use hint with an eachFrame EH,

as @gc8 stated, you can use an array to hold hint text, duration and even priority data and use your own functions to display the information as needed (ctrlCreate, etc.).

 

Cheers

Share this post


Link to post
Share on other sites

Yes, thanks for your comments. Managing an array seems to be a good solution. I'm not fond of an each frame EH just for hints, performance on mind. Creating a specific control? Same remark but the added value is that you don't care for some native hints (like "provider not available") which could override your hint. That was also an attempt...

I'm not really trying to hack the IGUI, just trying to wait for no message displayed in order to display one, then following one...

So, the message queue is a trick, the moment to display an element is another one (especially if I want to use the native hint).

 

Share this post


Link to post
Share on other sites

I've been using a function for hints with boolean flag for my missions.  Perhaps could revise for use with remote exec.  Hope it helps.

Spoiler

if (isNil "TAG_hintInProgress") then {TAG_hintInProgress = false};

_this spawn 
{
	if (_this != "") then 
	{
		// Set a 5 second delay between messages when hints are received back-to-back.
		waitUntil {sleep 0.25; !TAG_hintInProgress};
		TAG_hintInProgress = true;

		HintSilent "";
		sleep 0.25;
		HintSilent _this;

		sleep 4.75;
		TAG_hintInProgress = false;
	};
};

 

 

  • Thanks 1

Share this post


Link to post
Share on other sites
On 1/12/2020 at 10:13 AM, gc8 said:

You could put the messages in array and then get the first element from the array and display it 10 seconds and then delete it from array, then get next message from array and so on (the array would be in client)

This is pretty much how I did it. I sent the string to a manager script that counted the characters in the string which then displayed the hint for a time determined by the length of the string. It would also queue the hints so none got overwritten.

But after a while I did not like the look of hints and switched to HazJ's notification system.

Share this post


Link to post
Share on other sites
21 hours ago, pierremgi said:

I'm not fond of an each frame EH just for hints, performance on mind.

Can not see it effecting performance much if each iteration your only checking if time for next queued message has been reached (simple numerical evaluation). If not reached then just do nothing. Plus its only something handle by each client.

Spoiler

Quick example thrown together.



TAG_debug = true;
TAG_hintQueue_msgBoxSize = 0.1;

TAG_fnc_hintQueue = {
	params[ "_mode", "_this" ];

	switch ( toUpperANSI _mode ) do {

		case "ADD" : {
			if !( params[
				[ "_msg", "", [ "" ] ]
			] ) exitWith {
				"Blank message provided" call BIS_fnc_error;
			};

			( _this select[ 1, 3 ] ) params[
				[ "_showTime", 10, [ 0 ] ],
				[ "_tag", "", [ "" ] ],
				[ "_priority", -1, [ 0 ] ]
			];

			if ( isNil "TAG_hintQueue" ) then {
				TAG_hintQueue =[ [ _msg, _showTime, _priority, _tag ] ];
			}else{
				if ( _priority isEqualTo -1 ) then {
					TAG_hintQueue pushBack[ _msg, _showTime, _priority, _tag ];
				}else{
					_index = TAG_hintQueue findIf{ ( _x select 2 ) > _priority || ( _x select 2 ) isEqualTo -1 };
					if ( _index > -1 ) then {
						_queue = TAG_hintQueue select[ _index, count TAG_hintQueue ];
						TAG_hintQueue deleteRange[ _index, count TAG_hintQueue ];
						TAG_hintQueue pushBack[ _msg, _showTime, _priority, _tag ];
						TAG_hintQueue append _queue;
					}else{
						TAG_hintQueue pushBack[ _msg, _showTime, _priority, _tag ];
					};
				};
			};

			if ( isNil "TAG_hintQueue_EH" ) then {

				if ( isNil "TAG_hintQueue_nextMsgTime" ) then {
					TAG_hintQueue_nextMsgTime = time;
				};
				TAG_hintQueue_EH = addMissionEventHandler[ "EachFrame", {
					disableSerialization;
					//Next message
					if ( time > TAG_hintQueue_nextMsgTime && { !isNil "TAG_hintQueue" } && { !( TAG_hintQueue isEqualTo [] ) } ) then {
						TAG_hintQueue deleteAt 0 params[ "_msg", "_showTime", "_priority", "_tag" ];
						if ( !isNil "TAG_debug" && { TAG_debug } ) then {
							_origIndex = _msg splitString " " select 5;
							diag_log format[ "Shown Tag: %1, Original Index: %2 - Priority: %3", _tag, _origIndex, _priority ];
						};
						_nextIDC = if ( isNil "TAG_hintQueue_ctrls" ) then {
							TAG_hintQueue_ctrls = [];
							10
						}else{
							_lastCtrl = TAG_hintQueue_ctrls deleteAt 0;
							_lastCtrl ctrlSetFade 1;
							_lastCtrl ctrlCommit 1;
							_nul = [ _lastCtrl ] spawn {
								disableSerialization;
								params[ "_lastCtrl" ];
								waitUntil{ ctrlCommitted _lastCtrl };
								ctrlDelete _lastCtrl;
							};
							[ 10, 11 ] select ( ctrlIDC _lastCtrl isEqualTo 10 );
						};
						_newCtrl = findDisplay 46 ctrlCreate[ "ctrlStaticMulti", _nextIDC ];
						TAG_hintQueue_ctrls pushBack _newCtrl;
						_newCtrl ctrlSetPosition[
							safeZoneXAbs + safeZoneWAbs,
							safeZoneY + ( safeZoneH / 2 ),
							TAG_hintQueue_msgBoxSize * safeZoneWAbs,
							TAG_hintQueue_msgBoxSize * safeZoneH
						];
						_newCtrl ctrlSetBackgroundColor[ 0, 0, 0, 0.6 ];
						_newCtrl ctrlCommit 0;
						_newCtrl ctrlSetPosition[
							safeZoneXAbs + safeZoneWAbs - ( TAG_hintQueue_msgBoxSize * safeZoneWAbs ),
							safeZoneY + ( safeZoneH / 2 ),
							TAG_hintQueue_msgBoxSize * safeZoneWAbs,
							TAG_hintQueue_msgBoxSize * safeZoneH
						];
						_newCtrl ctrlCommit 1;
						_newCtrl ctrlSetText _msg;
						TAG_hintQueue_nextMsgTime = time + _showTime;
					};

					//Any tags to remove
					if ( !isNil "TAG_hintQueue_remove" && { !( TAG_hintQueue_remove isEqualTo [] ) } ) then {
						{
							_tag = TAG_hintQueue_remove deleteAt 0;
							_remove = TAG_hintQueue select{ ( _x select 3 ) == _tag };
							TAG_hintQueue = TAG_hintQueue - _remove;
						}forEach +TAG_hintQueue_remove;
						if ( TAG_hintQueue_remove isEqualTo [] ) then {
							TAG_hintQueue_remove = nil;
						};
					};

					//Is queue empty
					if ( TAG_hintQueue isEqualTo [] ) then {
						TAG_hintQueue = nil;
						TAG_hintQueue_remove = nil;
						removeMissionEventHandler[ "EachFrame", _thisEventHandler ];
						TAG_hintQueue_EH = nil;
						_nul = [] spawn {
							waitUntil{ time > TAG_hintQueue_nextMsgTime || !isNil "TAG_hintQueue" };
							if ( isNil "TAG_hintQueue" ) then {
								_lastCtrl = TAG_hintQueue_ctrls deleteAt 0;
								_lastCtrl ctrlSetFade 1;
								_lastCtrl ctrlCommit 1;
								_nul = [ _lastCtrl ] spawn {
									disableSerialization;
									params[ "_lastCtrl" ];
									waitUntil{ ctrlCommitted _lastCtrl };
									ctrlDelete _lastCtrl;
									TAG_hintQueue_ctrls = nil;
								};
								TAG_hintQueue_nextMsgTime = nil;
							};
						};
					};
				}];
			};

		};

		case "REM" : {
			if !( params[ [ "_tag", "", [ "" ] ] ] ) exitWith {
				"A 'TAG' must be provided to remove messages from the queue" call BIS_fnc_error;
			};

			if ( isNil "TAG_hintQueue_remove" ) then {
				TAG_hintQueue_remove = [ _tag ];
			}else{
				TAG_hintQueue_remove pushBack _tag;
			};
		};

	};
};


//TEST

_test = [] spawn {
	_test1s = 0;
	_test2s = 0;
	_test3s = 0;
	_msg = "This is a test message\nOriginal Index: %4\nPriority: %1\nShow Time: %2\nTag: %3";
	for "_i" from 1 to 20 do {
		_tag = selectRandom[ "test1", "test2", "test3" ];
		_priority = ( floor random 6 ) -1;
		_showTime = ( floor random 5 ) + 3;

		if ( _tag == "test1" ) then {
			_test1s = _test1s + 1;
		};
		if ( _tag == "test2" ) then {
			_test2s = _test2s + 1;
		};
		if ( _tag == "test3" ) then {
			_test3s = _test3s + 1;
		};

		[
			"ADD",
			[
				format[ _msg, _priority, _showTime, _tag, _i ],
				_showTime,
				_tag,
				_priority
			]
		] call TAG_fnc_hintQueue;
	};

	if ( !isNil "TAG_debug" && { TAG_debug } ) then {

		diag_log "";
		diag_log "";
		diag_log "NEW TEST";
		diag_log format[ "%1 test1, %2 test2, %3 test3 messages added to the queue", _test1s, _test2s, _test3s ];

		uiSleep (( floor random 15 ) + 15 );

		diag_log "Removing 'test2' messages";

		[ "REM", "test2" ] call TAG_fnc_hintQueue;

		uiSleep (( floor random 10 ) + 10 );

		diag_log "Removing 'test3' messages";

		[ "REM", "test3" ] call TAG_fnc_hintQueue;
	};

};

 

 

  • Like 4

Share this post


Link to post
Share on other sites

@Larrow    Thank you very much!  Cherry on the cake, your control is fine! Very good script (as usual).

  • Like 1

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

×