Jump to content
csk222

How to stop a script when running another script?

Recommended Posts

Hello. How can I stop a script from completing once it has started by overriding it by running another script? I have looked into terminate and exitwith, but I can't quite work it out. 

 

Example/Scenario: I send a helicopter to an insertion point (LZ1). Half way I don't want to go to LZ1 and give it a new insertion point (LZ2). Then I decide to just go back to base (RTB).

 

The helicopter will follow all of the commands and fly towards the insertion points and land back at base. Fine! But when it lands, all of the notifications from the previous insertion point orders will display back to back to back. How do I prevent that?

 

Insertion:

Spoiler

/*
Author: Cobra [BOMSF] 1949-2014
bomsfarma3@gmail.com - www.bomsf.enjin.com
You may re-use any of this work as long as you provide credit back to me.
	Edit By CSK222
		UH80 Alpha: LZ Alpha Insertion
*/
if (isServer or isDedicated) then {
	
	[["AirborneCommand",["Airborne Command", "UH80 Alpha moving to LZ Insertion"]], "BIS_fnc_showNotification", true, false] spawn BIS_fnc_MP;
	sleep 1;	
	uh80_alpha animateDoor ["door_L",0]; uh80_alpha animateDoor ["door_R",0];	
	uh80_alpha move (getMarkerPos "ainsrsp");
	uh80_alpha setBehaviour "CARELESS";
	uh80_alpha setSpeedMode "NORMAL";
	
	while { ((alive uh80_alpha) && !(unitReady uh80_alpha)) } do
	{
		sleep 1;
	};
	if ( (alive uh80_alpha) && (unitReady uh80_alpha) ) then
	{
		uh80_alpha land "LAND";
		alphasmokei1g = "SmokeShellRed" createVehicle (getMarkerPos "ainsrsp");
		alphachemi1g = "Chemlight_red" createVehicle (getMarkerPos "ainsrsp");		
		waitUntil {(isTouchingGround uh80_alpha)};
		uh80_alpha animateDoor ["door_L",1]; uh80_alpha animateDoor ["door_R",1]; 		
		[["AirborneCommand",["Airborne Command", "UH80 Alpha - Waiting for further instructions"]], "BIS_fnc_showNotification", true, false] spawn BIS_fnc_MP; sleep 1;	
		uh80_alpha setDamage 0;	uh80_alpha setFuel 1;
	};
};

 

RTB:

Spoiler

/*
Author: Cobra [BOMSF] 1949-2014
bomsfarma3@gmail.com - www.bomsf.enjin.com
You may re-use any of this work as long as you provide credit back to me.
	Edit By CSK222
		UH80 Alpha: Return To Base
*/
if (isServer or isDedicated) then {

	[["AirborneCommand",["Airborne Command", "UH80 Alpha returning to base"]], "BIS_fnc_showNotification", true, false] spawn BIS_fnc_MP;
	sleep 1;	
	uh80_alpha animateDoor ["door_L",0]; uh80_alpha animateDoor ["door_R",0];	
	uh80_alpha move (getMarkerPos "alphapad");
	uh80_alpha setBehaviour "CARELESS";
	uh80_alpha setSpeedMode "NORMAL";
				
	while { ((alive uh80_alpha) && !(unitReady uh80_alpha)) } do
	{
		sleep 1;
	};
	if ( (alive uh80_alpha) && (unitReady uh80_alpha) ) then
	{
		uh80_alpha land "LAND";
		waitUntil {(isTouchingGround uh80_alpha)};
		uh80_alpha animateDoor ["door_L",1]; uh80_alpha animateDoor ["door_R",1]; 		
		[["AirborneCommand",["Airborne Command", "UH80 Alpha standing by at base"]], "BIS_fnc_showNotification", true, false] spawn BIS_fnc_MP;
		uh80_alpha setDamage 0;	uh80_alpha setFuel 1;
	};
};

 

This runs the scripts

Spoiler

	class btnD5: abo_RscButton
	{
		idc = 5;
		action = "[] call abo_noshow_dbtns;ctrlShow [80,true];ctrlShow [97,true];ctrlShow [96,true];ctrlShow [79,false];_nulalz = [player] execVM 'bPad\abo\airborne\abo_ainsx.sqf';closeDialog 0;";
		text = "LZ"; //--- ToDo: Localize;
		tooltip = "Alpha Insertion/Pickup"; //--- ToDo: Localize;
		x = 0.1;
		y = 0.01;
		w = 0.19;
		h = 0.05;
	};
	class btnD6: abo_RscButton
	{
		idc = 6;
		action = "_nulartb = [player] execVM 'bPad\abo\airborne\abo_artbx.sqf';closeDialog 0;";
		text = "RTB"; //--- ToDo: Localize;
		tooltip = "Alpha Return To Base"; //--- ToDo: Localize;
		x = 0.3;
		y = 0.01;
		w = 0.19;
		h = 0.05;
	};

 

 

 

Here is an example video: Helicopter Insertion Script Run Multiple Times - Notifications Stack At The End

 

Thank you.

Share this post


Link to post
Share on other sites

Keep the state of the chopper in a variable (e.g. isRTB = false/true) and then add this line to insertion

...
while { ((alive uh80_alpha) && !(unitReady uh80_alpha)) } do
{
	sleep 1;
};
if isRTB exitWith {};
...

If you add it to both scripts then you can even change your mind multiple times.

Share this post


Link to post
Share on other sites

Can you explain this a little more. I have been plugging that code in different areas in the script with varying results. The best I got it to do was to cancel out the notifications, but at the end the chopper wouldn't land. Keep in mind that I also have to add this to the fastrope, parajump, and helocast scripts. If someone can provide a full working example, I can replicate it with the other scripts. So for now - using these 2 scripts (insertion & rtb) as an example, I need them to cancel each other out no matter how many times I choose. I think the insertion script needs to cancel itself out too if I choose to set a new LZ without completing the initial LZ or sending it back to base (if that makes sense).

 

Thanks

Share this post


Link to post
Share on other sites

OK, if you have more scripts then it's better to just terminate them. I know you wrote you tried it but it should work. Save your script handles when executing scripts and then terminate them.

Share this post


Link to post
Share on other sites

Thanks for your input so far  @theend3r

Can someone please give this a look and shed some light on this or is what I'm trying to do not possible?

 

Any and all guidance is very much welcome and appreciated!

Share this post


Link to post
Share on other sites
if (not isNil {scriptHandle} and {not scriptDone scriptHandle}) then {
       terminate scriptHandle};
scriptHandle = myAguments spawn myScript;

 

Share this post


Link to post
Share on other sites
On 1/31/2017 at 5:42 AM, serena said:

if (not isNil {scriptHandle} and {not scriptDone scriptHandle}) then {
       terminate scriptHandle};
scriptHandle = myAguments spawn myScript;

 

Can you explain this a little more for my use specifically.

 

I've been trying to "Frankenstein" all sorts of ways with the codes, but NOPE! Can't figure it out. Everything functions correctly and I know how to manage the helicopter where I'm not double stacking commands, but it still bothers me to know that if I wanted to land somewhere else, I'd have multiple notifications pop up ruining the experience. Any other takers?

Thanks.

Share this post


Link to post
Share on other sites

I am know nothing about your script with helicopters. My sample is only shows how to terminate script when starting another one.

 

In most cases force script termination is a bad practice that should be avoided. Correctly written script at the beginning of each cycle should check condition of completion and finalize itself, without side help.

 

The best way to debug your script - debug it by small parts, moving from one to another, to make them work properly. Also, you can launch game with -showScriptErrors startup parameter. SystemChat command allow trace what you want in mission running time. All scripting commands described here.

Share this post


Link to post
Share on other sites

This is generic sample of continuously working script:

MyContinouslyWorkingScriptSample = {
	while {IS_SCRIPT_SHOULD_CONTINUE_WORKING} do { // replace with real script finalize condition
		// here it should be done some useful work
		
		// how to trace script execution
		systemChat "Hey, I am still working...";
		
		// always at the end of cycle
		// important command, paused your script for given period in seconds
		sleep 1;
	};
	
	systemChat "Hey, I am finalizing. Bye!";
};

//To launch: [] spawn MyContinouslyWorkingScriptSample;

 

  • Like 1

Share this post


Link to post
Share on other sites

I am having a similar problem getting a repeating AI script to end. Built into my mission is a stealth section where the player has to infiltrate a base and do something. Normally Arma's godlike AI just notices you instantly and this would be impossible so i wrote, well mostly copied, this script from Feuerex youtube channel:

_fex_fnc_patrol = {
	_soldier = _this select 0;
	_logic = _this select 1;
	while {!alarm} do {
		_posx = position _logic select 0;
		_posy = position _logic select 1;
		_areadir = getDir _soldier + 45;
		_position = position player;
		_areax = 10;
		_areay = 10;
		_difx = (_position select 0)- _posx;
		_dify = (_position select 1) - _posy;
		_dir = aTan (_difx / _dify);
		if (_dify < 0) then {_dir = _dir + 180;};
		_relativedir = _areadir - _dir;
		_adis = abs(_areax / cos (90 - _relativedir));
		_bdis = abs (_areay / cos _relativedir);
		_borderdis = _adis Min _bdis;
		_positiondis = _position distance _logic;
		if (_positiondis < _borderdis) then {
		_ins = lineIntersectsSurfaces
		[
		eyePos player,
		eyePos _soldier,
		player,
		_soldier,
		true,
		1,
		"GEOM",
		"NONE"
		];
		if (isNil {_ins select 0}) then {
			alarm = true;
			player setCaptive false;
			hint "He's inside the area.";
			{if (side _x == east) then {
			_px = ((position player select 0) + (Random (15)) - 30);
			_py = ((position player select 1) + (Random (15)) - 30);
			_x move [_px, _py,0];}} forEach AllUnits;
			{if (side _x == sideLogic) then {deleteVehicle _x}} forEach AllUnits;
			sleep 40;
			player setCaptive true;
			{if (side _x == east) then {
			_x move position iCenter;}} forEach AllUnits;
			if (true) exitWith {alarm = false;  _again = [] execVm "stealthscript.sqf";};
			} else {
			hint "He's inside, but hidden";
			};
		}
		else {
		hint "He's outside.";
		};
	sleep 0.5;
	};

};


_enemyArray = [];
_i = 0;
{if (side _x == east) then {_enemyArray set [_i, _x]; _i = _i + 1};} forEach allUnits;
_center = createCenter sideLogic;
_group = createGroup _center;
player setCaptive true;
for "_j" from 0 to (count _enemyArray) - 1 step 1 do {
"Logic" createUnit [position (_enemyArray select _j), _group,
"this AttachTo [(_enemyArray select _j), [0,14,0.5]];
_anythi = [_enemyArray select _j, this] spawn _fex_fnc_patrol;"];
sleep 0.1;
}; 

Basically all I've been able to do with it is remove the alarm trigger related lines because the script won't work with them and adjusted the size and location of the vision cone. The hints are simply there to debug and will be removed once i get it working fully.

 

What I need help with is getting the script to end once its started. Because my mission involves the whole island and this stealth section is only an objective within it I need to be able to deactivate the code so that all of the units don't follow it all the time. It's saved as "stealthscript.sqf" which is ExecVM'ed from a trigger when the player is within a given radius of the objective and it is within a certain time of day (night time). Unfortunately I have been able to neither stop the script entirely once its activated, which would be ideal for performance reasons, or manage to get it to only run for certain units.

 

So far I've tried making the while {} do {} loop at the start trigger and alarm activated, removing  _again = [] execVm "stealthscript.sqf" and replacing it with a terminate command, calling terminate stealthscript from another trigger, calling terminate.sqf from a trigger with:

if (not isNil {stealthscript} and {not scriptDone stealthscript}) then {
       terminate stealthscript};

As well as putting in waitUntil {triggeractivated whatevertrigger}; lines in where I could think and nothing seems to work. Putting a trigger in the while {} do {} loop at the start to while {!alarm && triggeractivated whatevertrigger} seems to stop the script but it results in the AI being permanently unable to detect the player as it seems they are set to captive true.

 

I'm starting to get really frustrated with this and would love some help,

 

thanks,

Ian

 

 

 

 

Share this post


Link to post
Share on other sites

Please! If anyone could help that would be awesome.This is the only bit I can't figure out for my mission to be ready.

Share this post


Link to post
Share on other sites

hope I've come to the right place.

I need to terminate a script that is part of an add action...

the script is...
pickupaction = PC1 addAction [("<t color=""#cd0000"">") + ("PICK UP") + "</t>", "MissionScripts\CALLER.sqf", [false], 1, false, true, "", "Player distance PC1 <3"];

and in another script, I have tried...
terminate pickupaction; 

and it does not work, any ideas?

Share this post


Link to post
Share on other sites
On 08/05/2018 at 7:54 AM, PSYKO_nz said:

hope I've come to the right place.

I need to terminate a script that is part of an add action...

the script is...
pickupaction = PC1 addAction [("<t color=""#cd0000"">") + ("PICK UP") + "</t>", "MissionScripts\CALLER.sqf", [false], 1, false, true, "", "Player distance PC1 <3"];

and in another script, I have tried...
terminate pickupaction; 

and it does not work, any ideas?

hi,
I know it's a long time. But did you found a solution. Because I have the same problem. After a Ace_Action I want the player can do an another one but On himself a SelfAction. So I try in the first time to do it with a simple addAction but it doesn't work  :(

Share this post


Link to post
Share on other sites

You are trying to terminate the action, not the script. You need to keep the script handle and terminate that instead.

 

But if your mission is an MP mission you will also have a locality issue to solve. I.e. the script must be terminated on the machine running it, not on the machine where the player selecting the action is.

 

And also, i'ts usually a bad practice to terminate scripts. A better approach is to set a global variable or something, that the script checks, so that the script can close itself in a more controlled manner.

  • 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

×