Jump to content
Sign in to follow this  
alleycat

Exiting a script + waituntil problem

Recommended Posts

I am trying to END this script after a player clicks once. However it stays active and never finishes.

_markers = allMapMarkers;
//{ _x setMarkerColor "ColorBlack"; } forEach _markers;
finished = false;
hint "Click on map to move mission area";
_posplayer = getpos player;

//openmap true;
while {alive player or visibleMap} do {

onMapSingleClick    "player setpos _pos; onMapSingleClick ''; true";
					
onMapSingleClick     " 
                    global_pos=_pos;
					
                    finished = true;
                    onMapSingleClick '';        
                    [player,global_pos]		execVM			""strat\client\check_dist.sqf"";
                    
                    true";

waitUntil {finished};
sleep 0.1;
finished = true;


//hint format ["Distance from start to end: %1", _posplayer distance global_pos];
};

if (true) exitWith {};
//diag_log text format ['Distance from start to end: %1', _posplayer distance global_pos];

Share this post


Link to post
Share on other sites

One issue I see is you used many onMapSingleClick event handlers. Problem is that there can only be one onMapSingleClick active at one time. In order to stack multiple onMapSingleClick's, use BIS_fnc_addStackedEventHandler instead. As a matter of fact you should always use BIS_fnc_addStackedEventHandler instead of onMapSingleClick to ensure compatibility with other scripts.

 

To remove the EH, you should be using BIS_fnc_removeStackedEventHandler instead of using onMapSingleClick "".

Share this post


Link to post
Share on other sites

if....exitWith should be inside while do scope but it appears to be outside.

That was an attempt to quickly get out of the script, without this it still fails. What I do not understand is why the waituntil does block progression because i have set finished to true.

Share this post


Link to post
Share on other sites

while {alive player or visibleMap} do {

    ....
};

The while loop will continue as long as either "the player is alive" OR "the map is open". In this case you need to kill the player AND close the map for the loop to end.

  • Like 1

Share this post


Link to post
Share on other sites

That was an attempt to quickly get out of the script, without this it still fails. What I do not understand is why the waituntil does block progression because i have set finished to true.

 

Your method of aborting the loop works for me, as long as you keep exitwith inside the loop:

[] spawn
{
	finished = false;
	onMapSingleClick "finished = true";
	while {true} do
	{
		systemChat "waitloop";
		waitUntil {finished};
		if (true) exitWith {};
	};
	systemChat "finished";
};

Share this post


Link to post
Share on other sites

Thanks for the help but I think I still got it wrong

_markers = allMapMarkers;
//{ _x setMarkerColor "ColorBlack"; } forEach _markers;
finished = false;
hint "Click on map to move mission area";
_posplayer = getpos player;

//openmap true;
while {alive player or visibleMap} do {

onMapSingleClick    "player setpos _pos; onMapSingleClick ''; true";
					
onMapSingleClick     " 
                    global_pos=_pos;
					
                    finished = true;
                    onMapSingleClick '';        
                    [player,global_pos]		execVM			""strat\client\check_dist.sqf"";
                    
                    true";

waitUntil {finished};
sleep 0.1;
//finished = true;

	while {true} do
	{
		systemChat "waitloop";
		waitUntil {finished};
		if (true) exitWith {};
	};
	systemChat "finished";

};

This works (the markers move when clicking on the map) and I get the system messages. But the functionality never stops. When a player closes the map, and then opens it again (without using the action from an object) he can still move the markers around. I would like to this to stop functioning after the first time.

Share this post


Link to post
Share on other sites

i would suggest

onMapSingleClick "";

after your loop is finished.


Container:

Spoiler

 



Saro_fnc_rnd_civ_bomber =
{
 params [["_civ", objNull,[objNull]], ["_chance", 3, [0]]];

 if ((random 100 > _chance) || (isNull _civ)) exitWith {true};

 _this spawn
 { 
  params ["_bomber"];
  private _target_players = [];

  while {(alive _bomber) && !(isNull _bomber)} do
  {

   // wait until players are in range
   waitUntil 
   {
    sleep (5 + random 10);
    _target_players = (allPlayers - entities "HeadlessClient_F") select {(alive _x) && ((_x distance _bomber) < 200)};
    ((count _target_players > 0) || !(alive _bomber) || (isNull _bomber))
   };

   // end everything if suicide bomber is already dead
   if (!(alive _bomber) || (isNull _bomber)) exitWith {};

   // follow nearest player
   while {alive _bomber && !(isNull _bomber)} do
   {
    private _plyr_cnter = 0;
    private _sort_array = []

    // get nearest player
    _target_players = _target_players apply {[_x distance _bomber, _x]};
    _target_players sort true;
    _target = _target_players select 0 select 1;
    _can_see = [_target, "VIEW", _bomber] checkVisibility [eyePos _target, eyePos _bomber];
    _wp = currentWaypoint group _bomber;
    _wp setWaypointPosition [position _target, 0];
    if ((_can_see < 0.3) || _close2target) then
    {
     _wp setWaypointSpeed "FULL";
    }
    else
    {
     _wp setWaypointSpeed "NORMAL";
    }; 
 

   } // end follow while
   
      
    _boom = "M_Mo_82mm_AT_LG" createVehicle (getPos _this);
  } // main while end
 } //spawn end
} //fnc end

 

 

Share this post


Link to post
Share on other sites

i would suggest

onMapSingleClick "";

after your loop is finished.

_markers = allMapMarkers;
//{ _x setMarkerColor "ColorBlack"; } forEach _markers;
finished = false;
hint "Click on map to move mission area";
_posplayer = getpos player;

//openmap true;
while {alive player or visibleMap} do {

//onMapSingleClick    "player setpos _pos; onMapSingleClick ''; true";
					
onMapSingleClick     " 
                    global_pos=_pos;
					
                    finished = true;
                    onMapSingleClick '';        
                    [player,global_pos]		execVM			""strat\client\check_dist.sqf"";
                    
                    true";

waitUntil {finished};
sleep 0.1;
//finished = true;

	while {true} do
	{
		systemChat "waitloop";
		waitUntil {finished};
		if (true) exitWith {};
	};
	systemChat "finished";
	
};
onMapSingleClick '';

Tried that, does not work.

Share this post


Link to post
Share on other sites
_markers = allMapMarkers;
player setVariable ["_canDo", true];
hint "Click on map to move mission area";
_posplayer = getpos player;
while {alive player && visibleMap && !isNil {player getvariable "_canDo"}} do {
	onMapSingleClick " 
		global_pos=_pos;
		onMapSingleClick '';        
		[player,global_pos] execVM ""strat\client\check_dist.sqf"";
		player setVariable [""_canDo"", nil];
		true
	";
};
onMapSingleClick '';

This should work. ;)

 

Edit : By the way, isn't that the way it should be done?

onMapSingleClick " 
	global_pos=_pos;
	if (alive player) then {      
		[player,global_pos] execVM ""strat\client\check_dist.sqf"";
	};
	true
";

I'm not sure why you need the loop in the first place?

Share this post


Link to post
Share on other sites
_markers = allMapMarkers;
player setVariable ["_canDo", true];
hint "Click on map to move mission area";
_posplayer = getpos player;
while {alive player && visibleMap && !isNil {player getvariable "_canDo"}} do {
	onMapSingleClick " 
		global_pos=_pos;
		onMapSingleClick '';        
		[player,global_pos] execVM ""strat\client\check_dist.sqf"";
		player setVariable [""_canDo"", nil];
		true
	";
};
onMapSingleClick '';

This should work. ;)

Doesn't that keep constantly adding onMapSingleClick actions?

_markers = allMapMarkers;
finished = false;
hint "Click on map to move mission area";
_posplayer = getpos player;

onMapSingleClick     " 
                    global_pos=_pos;
					
                    finished = true;
                    onMapSingleClick '';        
                    [player,global_pos]	execVM 'strat\client\check_dist.sqf';
                    
                    true";

waitUntil {finished || !alive player || !visibleMap};
onMapSingleClick '';
  • Like 1

Share this post


Link to post
Share on other sites

Yes, that's why I was asking Alleycat why he put it in a loop. ^^

Share this post


Link to post
Share on other sites
//////////////////////////////////////////////////////////////////////////////
_markers = allMapMarkers;
//{ _x setMarkerColor "ColorBlack"; } forEach _markers;
finished = false;
hint "Click on map to move mission area";
_posplayer = getpos player;

openmap true;



					
onMapSingleClick " 
	global_pos=_pos;
	if (alive player) then {     

		[player,global_pos] execVM ""strat\client\check_dist.sqf"";
		finished = true;
	};
	true
";

waitUntil {finished};
onMapSingleClick '';

Thanks everyone, this way it works.

Share this post


Link to post
Share on other sites
On 26/02/2016 at 12:12 PM, alleycat said:

//////////////////////////////////////////////////////////////////////////////
_markers = allMapMarkers;
//{ _x setMarkerColor "ColorBlack"; } forEach _markers;
finished = false;
hint "Click on map to move mission area";
_posplayer = getpos player;

openmap true;



					
onMapSingleClick " 
	global_pos=_pos;
	if (alive player) then {     

		[player,global_pos] execVM ""strat\client\check_dist.sqf"";
		finished = true;
	};
	true
";

waitUntil {finished};
onMapSingleClick '';

Thanks everyone, this way it works.

Me thinks this is more elegant:

while {true}

do

{

    waitUntil {visibleMap};

    hint "visable map";

 

    _myEH = (findDisplay 12) displayAddEventHandler

    ["mouseButtonDown",

    {

        _ctrl = _this select 0;

        _x = _this select 2;

        _y = _this select 3;

 

        hint str _this;

 

        if(_this select 5) then

        {

            hint str _this;

        }

        else

        {

        };

    }

    ];

 

    waitUntil {!visibleMap};

    (findDisplay 12) displayRemoveEventHandler ["mouseButtonDown", _myEH];

    hint "map not visable.";

};

 

Share this post


Link to post
Share on other sites
On 26/02/2016 at 12:12 PM, alleycat said:

//////////////////////////////////////////////////////////////////////////////
_markers = allMapMarkers;
//{ _x setMarkerColor "ColorBlack"; } forEach _markers;
finished = false;
hint "Click on map to move mission area";
_posplayer = getpos player;

openmap true;



					
onMapSingleClick " 
	global_pos=_pos;
	if (alive player) then {     

		[player,global_pos] execVM ""strat\client\check_dist.sqf"";
		finished = true;
	};
	true
";

waitUntil {finished};
onMapSingleClick '';

Thanks everyone, this way it works.

Me thinks this is more elegant approach, yes.


 

while {true}

do
{
    waitUntil {visibleMap};

    _myEH = (findDisplay 12) displayAddEventHandler

    ["mouseButtonDown",

    {
        _ctrl = _this select 0;

        _x = _this select 2;

        _y = _this select 3;

        hint str _this;

        //i only want to do stuff whn CTRL button is pressed as well.
        if(_this select 5) then
        {
            hint str _this;
            //do your stuff here on CTRL + LBM click
        }
        else
        {
            //if not do nothing, or something. entirely depends on you, yes?
        };
    }
    ];

    waitUntil {!visibleMap};

    (findDisplay 12) displayRemoveEventHandler ["mouseButtonDown", _myEH];

    hint "map not visable.";

};

 

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  

×