Jump to content

Recommended Posts

Hello, I am curious, is there a way I can stop looping script using text chat? For example:
Script like:

if (!isServer) exitWith {};
[] spawn { 
while{true} do {
this setObjectTextureGlobal [0, "#(argb,8,8,3)color(0.9,0.1,0.9,0.3)"];
sleep 1;
this setObjectTextureGlobal [0, "#(argb,8,8,3)color(0.9,0.1,0.1,0.3)"];
sleep 1;
this setObjectTextureGlobal [0, "#(argb,8,8,3)color(0.1,0.9,0.1,0.3)"];
sleep 1;
this setObjectTextureGlobal [0, "#(argb,8,8,3)color(0.5,0.1,0.5,0.5)"];
sleep 1;
this setObjectTextureGlobal [0, "#(argb,8,8,3)color(0.1,0.1,0.9,0.3)"];
sleep 1;
this setObjectTextureGlobal [0, "#(argb,8,8,3)color(0.1,0.5,0.5,0.5)"];
sleep 1;
this setObjectTextureGlobal [0, "#(argb,8,8,3)color(0.9,0.9,0.1,0.6)"];
sleep 1;
};
};

Would it be possible to for example type in chat smth like "terminate script" and it would stop looping, or well, stop in general?
 

Share this post


Link to post
Share on other sites

You're using

while {true} do

Just use a variable instead and set that to false when you want the loop to stop.

That's the main usage of while loops, being able to be stopped at any time.

 

Cheers

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

There is still the issue of running code from text chat. I found a script system from A2 that purported to allow this:  

Unlikely it will work out of the box, if at all, but it might point you in the right direction.

 

Unless there's some new function for A3 that already does this, of course...

Share this post


Link to post
Share on other sites

According to BIki, spawn returns a script handle which can be used to check if the script is done or terminate it. For your case, you would most probably need to call terminate on the script handle. A possible implementation would be (emulating your script with the implementation details skipped)

// Run only on the server
if(!isServer) exitWith {};

// Call the while-loop with the script you want to run and get a handle to it
scriptHandle = [] spawn {
	// In here place the while-loop you wish to run
};

Now, you can use the scriptHandle variable to terminate the script whenever you wish. You can do that with

// Terminate the script
terminate scriptHandle;

Please note two things:

1) According to the documentation of terminate the script will not be terminated immediately, but only the next time it will be processed by the scheduler.

2) In the code I provided the scriptHandle variable is global to the server (since you make sure the script won't run in any other PC than the server). This way you can have access to the handle from other scripts in the server. I am not sure how you could have access to the handle from another computer since according to the publicVariable documentation you cannot broadcast scripts (which is what the returned handle is, according to spawn documentation). Maybe someone around here could provide some alternatives.

 

Hope this helps in one way or the other, or at least give some hints to a possible (better) solution.

  • Like 1

Share this post


Link to post
Share on other sites

How to stop a script that contains "sleep" :

garnison/repatrol.sqf

[crewarm1, getPos centarZP, 1000, 4, "MOVE", "SAFE", "RED", "NORMAL"] call cba_fnc_taskPatrol;                                        

systemChat "Patrol routes changed. Next shift in few mins";

nul=[]execVM "garnison.repatrol.sqf"; sleep 120;

 

This is my try that don't work:

_stop = [] execVM "garnison\repatrol.sqf"; sleep .5;
terminate _stop;

 

Share this post


Link to post
Share on other sites

https://community.bistudio.com/wiki/terminate

Quote

The given script will not terminate immediately upon terminate command execution, it will do so the next time the script is processed by the scheduler

 

But that might not be what's going on here. Let's take a look:

[crewarm1, getPos centarZP, 1000, 4, "MOVE", "SAFE", "RED", "NORMAL"] call cba_fnc_taskPatrol;                                        
systemChat "Patrol routes changed. Next shift in few mins";
nul=[]execVM "garnison.repatrol.sqf"; sleep 120;

 

So, what's happening here?

  1. call CBA function
  2. message
  3. execVM script (goto "1")
  4. sleep 

You are creating a new patrol every frame (or as fast as your PC can process this)

 

Should be:

[crewarm1, getPos centarZP, 1000, 4, "MOVE", "SAFE", "RED", "NORMAL"] call cba_fnc_taskPatrol;                                        
systemChat "Patrol routes changed. Next shift in few mins";
sleep 120;
nul=[]execVM "garnison.repatrol.sqf"; 

 

Now, the reason why you can't terminate this is that the script is being re-instantiated from within, with the a "nul" handle. Instead, maybe use a while loop:

while {true} do {
	[crewarm1, getPos centarZP, 1000, 4, "MOVE", "SAFE", "RED", "NORMAL"] call cba_fnc_taskPatrol;                                        
	systemChat "Patrol routes changed. Next shift in few mins";
	sleep 120;
};

The while condition also allows you to use other means to stop the script/loop, like a global boolean, an alive check on a specific unit, etc.

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

Thanks for the lesson answer mate! So my understanding of this is that the script is not terminating the whole .sqf but "statement" inside it and that statement is defined by:

scriptHandle = [] spawn {
    while {true} do {

    [crewarm1, getPos centarZP, 1000, 4, "MOVE", "SAFE", "RED", "NORMAL"] call cba_fnc_taskPatrol;
    systemChat "Patrol routes changed. Next shift in few mins";
    sleep 5;
};
};

like ZaellixA said in the upper post and after that, terminate command: 

terminate scriptHandle; will do the job and will stop part inside "while" in .sqf itself. I tried this and it is working but point me out please again if I misunderstand your answer or check OK if I understand well - if that is what you are meaning.

Anyway thanks a lotttt for your time and help 
 

Share this post


Link to post
Share on other sites

Looking at your original example:

_stop = [] execVM "garnison\repatrol.sqf"; 
sleep .5;
terminate _stop;

The script "repatrol.sqf" is now being executed with the attached script handle "_stop."

 

Terminating "_stop" will terminate that instance of the script.

 

However, the script re-instantiates itself using a nul script handle, which is completely outside the scope of the original script handle "_stop." Once the "_stop" instance executes, it is done - there is nothing to terminate.

 

UOyRTQJ.png

 

Creating a loop in the original script instead will allow you to maintain control of the process through the "_stop" script handle.

 

 

 

 

 

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

Yea, that's exactly what I want to say but my English is not precise enough. I understand you very well and I do it this way in original mission:

repatrol.sqf

scriptHandleP = [] spawn {
    while {true} do {
rad_01 sideChat "Patrol routes changed";
systemChat "Patrol routes changed. Next shift in six hours."; sleep 1;

//DERIVATIVES--------------------------------------------------------------------------------------------------
pveh1 setFuel 1;
pveh2 setFuel 1; sleep 0.5;

//REPATROL PESADIJSKA ZONA
[crewpveh1, getPos centarZP, 1000, 4, "MOVE", "SAFE", "RED", "NORMAL"] call cba_fnc_taskPatrol;

_newPos = [centarZP, 10, 1200, 20, 0, 0.4, 0] call BIS_fnc_findSafePos;
crewpveh2 move _newPos; sleep 0.5;

[ppat3, getPos centarZP, 1100, 5, "MOVE", "SAFE", "RED", "LIMITED"] call cba_fnc_taskPatrol; sleep 120;
};
};

After that, I just need to run terminate scriptHandleP from anywhere and it stops the loop. (so completely remove "nul" from procces)

Share this post


Link to post
Share on other sites

Something happened to "terminate handler" and now I can not stop the script. Please if anyone has some solution.

 

Runned (flight0.sqf):

letHandle = [] spawn {
    while {true} do {
sleep .4; systemChat "autopilot ON";
avi_03 flyInHeight 5; sleep 1;
avi_03 flyInHeight 50; 
};
};

 

Handler (flight1.sqf):

terminate letHandle; sleep .5;
avi_03 flyInHeight 55;
systemChat "autopilot OFF";

 

The first one is running all the time and the second one does nothing when fired. Only system chat is shown but the first script (flight0.sqf) is still in progress.

I am done diagnostic with [] spawn {copyToClipboard str diag_activeSQFScripts; }; and the script is there so maybe if I delete it manually from memory (edit a saved file of the mission)?

Share this post


Link to post
Share on other sites

Still can't fix this. Is there a way to FORCE stop all running scripts in the scheduler? I can't find anything about it. Also, loading the saved game didn't help nor did the manually deleting lines in the save file. Please, there must be a way. Thanks in advance

Share this post


Link to post
Share on other sites

Maybe check the script itself?

hint str scriptDone letHandle;

 

Share this post


Link to post
Share on other sites

For some reason, copying (forum) and pasting to the game (debug) does not work and that takes me all night killing my nervous system until I manually write codes in debug. 

hint str scriptDone letHandle;  

It is false.

Share this post


Link to post
Share on other sites

Of course, a while TRUE loop... never end, without exit.

You should set a condition:

While {isNil "blabla"} do { ....};

Be sure blabla doesn't exist yet.

Then, in flight1.sqf, at due time, blabla = TRUE; // or anything else.


 

Spoiler

 

or even:

while {true} do {
   if (!isNil "blabla") exitWith {hint "end of flight0.sqf"};
...};

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Please mate, break this down again because I barely understand.

This is clear ok: 

1 hour ago, pierremgi said:

Of course, a while TRUE loop... never end, without exit

But this:

 

1 hour ago, pierremgi said:

While {isNil "blabla"} do { ....};

Be sure blabla doesn't exist yet

All I need to do is to stop flight0.sqf. For some reason, flight1.sqf where the handler is triggered, does not stops the flight0.sqf anymore. So if I understand you well, I need to make a new condition (to hook flight0 to it) so I can use it cond to manipulate code? If so, please tell me step by step. 

 

tried in debug cons and guess what - doesn't work:

While {isNil "blabla"} do {letHandle};  blabla = true;  (let1.sqf still works, I know that because system chat is continuously showing "autopilot ON")

While {isNil "blabla"} do {terminate letHandle}; blabla = true;

While {isNil "blabla"} do {skripte\flight0.sqf}; blabla = true;

Share this post


Link to post
Share on other sites
54 minutes ago, Nemanjic said:

Please mate, break this down again because I barely understand.

This is clear ok: 

But this:

 

All I need to do is to stop flight0.sqf. For some reason, flight1.sqf where the handler is triggered, does not stops the flight0.sqf anymore. So if I understand you well, I need to make a new condition (to hook flight0 to it) so I can use it cond to manipulate code? If so, please tell me step by step. 

 

tried in debug cons and guess what - doesn't work:

While {isNil "blabla"} do {letHandle};  blabla = true;  (let1.sqf still works, I know that because system chat is continuously showing "autopilot ON")

 

NO!

If you set blabla to true; the loop will halt. That doesn't mean the systemchat disappear at once.

 

Let's try:

0 = [] spawn {while {isNil "blabla"} do {
  uisleep 0.1;
  hint str round diag_tickTime
}};


run it.
now in debug console:
blabla = TRUE  (or 0 or 1 or what you want, if working). Hint halt.( you can clear it by hint "";)

 

OR... you also have a loop in let1.sqf or flight1.sqf... I'm lost in your scripts.

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Ok trying now...

 

edited:

I do all of it.  0 = [] spawn {while {isNil "vlavla"} do { uisleep 0.1; hint str round diag_tickTime }}; gives number in hint. After that, I clear that hint with "". Then I run vlavla = true; Old script is still running (systemChat still shows new message every 1.4 second as let0.sqf is telling it to do). I know it because I run another system chat "check" it is shown and right after "autopilot ON" again and again. 

I put vlavla instead blabla on purpose - in case blabla is used by game now during previous testings.

Share this post


Link to post
Share on other sites
34 minutes ago, pierremgi said:

OR... you also have a loop in let1.sqf or flight1.sqf... I'm lost in your scripts.

I see this just now. 

Scripts are:

("LET" original name on Serbian) I wrote in English "FLIGHT" which is the same file name, sorry for confusing you. So originals are:

 

let0.sqf 

letHandle = [] spawn {
    while {true} do {
sleep .4; systemChat "аутолет";
avi_03 flyInHeight 5; sleep 1;
avi_03 flyInHeight 50; 
};
};

 

let1.sqf

terminate letHandle; sleep .5;
avi_03 flyInHeight 55;
systemChat "аутолет обустављен";

 

I use it because AI pilots are flying weirdly when multiple groups are in a helicopter (old problem with flying straight to huge altitudes and then taking on wp from there). This way I make a loop so pilots fly at normal altitudes. avi_03 is a helicopter. I need to say that this was working properly until yesterday. 

Those are original files so please if you can understand what's going on? Why is letHandle lost control over let0.sqf and how to gain it again? I hope I am writing more clearly now and thank you for your time friend!

Share this post


Link to post
Share on other sites

This works for me:

let0.sqf 

[] spawn {
    while {sleep 4; isNil "someVar"} do {
      systemChat "аутолет";
      avi_03 flyInHeight 5;
      sleep 1;
      avi_03 flyInHeight 50; 
  };
};

 

let1.sqf

someVar = TRUE;
avi_03 flyInHeight 55;
systemChat "аутолет обустављен";

 

or...

you can wait for 2.14 version and forget the loop:

avi_03 flyInHeight [50, true];  // 2nd param WILL force the helo for this height.

See also flyInHeightASL with standard, combat, and stealth attitude, already working.

Imho, you don't need loop for that.

 

 

Share this post


Link to post
Share on other sites

Will try this tonight and report back. 

 

33 minutes ago, pierremgi said:

or...

you can wait for 2.14 version and forget the loop:

wonderful news! I just wonder where you find this info? Here is nothing about it. 

 

34 minutes ago, pierremgi said:

See also flyInHeightASL

Same thing as normal flyInHeight no matter on group/unit/pilot behaviour.

Share this post


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

Of course, a while TRUE loop... never end, without exit.

 

You can definitely terminate a script containing a < while {true} > loop, but agreed that using even a simple Boolean condition is better.

Share this post


Link to post
Share on other sites
On 8/11/2023 at 2:47 PM, Nemanjic said:

Will try this tonight and report back. 

 

wonderful news! I just wonder where you find this info? Here is nothing about it. 

 

Same thing as normal flyInHeight no matter on group/unit/pilot behaviour.

 

aircraft flyInHeightASL [standardAltitude, combatAltitude, stealthAltitude]

Share this post


Link to post
Share on other sites

With "the same thing as normal flyInHeight" I mean the same problem if use flyInHeightASL, but thanks anyway. Still have not fixed this, no time for the next 2 weeks during the vacation. Will text when back home.

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

×