Jump to content
Sign in to follow this  
SD_BOB

Exit .SQF

Recommended Posts

Hello, i hope someone would be kind enough to help me with this.

I'm trying to learn .sqf (taking me a while lol), i've got an air support script that i am trying to modify with an exit option incase the person using the script inadvertently clicks the wrong place on the map.

Here is the part of the script that i am trying to modify:

_man = _this select 1;
_id = _this select 2;

_man removeAction asf1;
_man removeAction asf2;
_man removeAction asf5;

if (ASHEL == ASnumHEL) then {
as0 = _man addAction [localize "STR_MENUASM","airSup\addMenu.sqf",[], 5, false, false, "", "_target == player"];
_man groupChat localize "STR_NOMORE";
kill8 = true;
};
if(kill8)exitwith{trans = false;};

ASTRN = ASTRN + 1;

// from here

_man groupChat localize "STR_MAPPIK";
_asloc = createMarkerLocal ["asloc", [0,0,0]];
_asloc setMarkerShapeLocal "ICON";
_asloc setMarkerColorLocal "ColorGreen";
"asloc" setMarkerTypeLocal "hd_pickup";
onMapSingleClick "'asloc' setMarkerPosLocal _pos,ASclick = true";
waitUntil {ASclick};
onMapSingleClick "";
ASclick = false;

[color="Red"]/////////////////////INSERT CANCEL ACTION HERE/////////////////[/color]

// to here

_man groupChat localize "STR_MAPDRO";
_asloc2 = createMarkerLocal ["asloc2", [0,0,0]];
_asloc2 setMarkerShapeLocal "ICON";
_asloc2 setMarkerColorLocal "ColorGreen";
"asloc2" setMarkerTypeLocal "hd_end";
onMapSingleClick "'asloc2' setMarkerPosLocal _pos,ASclick = true";
waitUntil {ASclick};
onMapSingleClick "";
ASclick = false;

_asloc = getMarkerPos "asloc";
_asloc2 = getMarkerPos "asloc2";

_spwn = getPos ASpad;
_spwndir = getDir ASpad;
_grp1 = creategroup side _man;

IPheloAS = true;

_marker = createMarkerLocal ["aircraftmarker1", position ASpad];
_marker setMarkerShapeLocal "ICON";
"aircraftmarker1" setMarkerTypeLocal "b_air";

_spwn1 = [(_spwn select 0) - 30,(_spwn select 1) + 30,_spwn select 2];

_AShelo1 = createVehicle [airSupTRN, _spwn1, [], 0, "FLY"];
_AShelo1 setdir _spwndir;

_pilot1 = _grp1 createUnit [airSupPIL, _spwn, [], 0, "FORM"];
_pilot2 = _grp1 createUnit [airSupPIL, _spwn, [], 0, "FORM"];
_pilot3 = _grp1 createUnit [airSupPIL, _spwn, [], 0, "FORM"];
_pilot4 = _grp1 createUnit [airSupPIL, _spwn, [], 0, "FORM"];

_pilot1 moveindriver _AShelo1;
_pilot2 moveinturret [_AShelo1,[2]];
_pilot3 moveinturret [_AShelo1,[0]];
_pilot4 moveinturret [_AShelo1,[1]];

_lz1 = "HeliHEmpty" createVehicle _asloc;
_lz2 = "HeliHEmpty" createVehicle _asloc2;

[_AShelo1] spawn {
_AShelo1 = _this select 0;
while{IPheloAS} do {
	"aircraftmarker1" setMarkerPosLocal getPos _AShelo1;
	sleep 1;
};
if(true)exitWith{deletemarker "aircraftmarker1";};
};

[_AShelo1] spawn {	
_AShelo1 = _this select 0;
while{IPheloAS} do {
	if !(isEngineOn _AShelo1)then{_AShelo1 setdamage 1;};
};
if(true)exitWith{};
};

[_AShelo1] spawn {	
_AShelo1 = _this select 0;
while{IPheloAS} do {
	if (!alive _AShelo1) then {IPheloAS = false}
};
if(true)exitWith{};
};

_man groupChat localize "STR_TRANINC";

landed = false;
takeoff = false;

g1wp1=_grp1 addWaypoint [_asloc, 75];
g1wp1 setWaypointBehaviour "CARELESS";
g1wp1 setWaypointType "LOAD";
[_grp1, 1] setWaypointStatements ["true", "landed = true"];
_AShelo1 addAction [localize "STR_GTGPIL","airSup\takeOff.sqf"];
waituntil {(!IPheloAS) or (landed)};
_AShelo1 land "get in";
waituntil {(!IPheloAS) or (!alive _man) or (takeoff)};

landed = false;

g1wp2=_grp1 addWaypoint [_asloc2, 75];
g1wp2 setWaypointBehaviour "CARELESS";
g1wp2 setWaypointType "LOAD";
[_grp1, 2] setWaypointStatements ["true", "landed = true"];
waituntil {(!IPheloAS) or landed};
_AShelo1 land "get out";
waituntil {(!IPheloAS) or (0 >= count ((crew _AShelo1)-[_pilot1,_pilot2,_pilot3,_pilot4]))};

g1wp3=_grp1 addWaypoint [_spwn, 0];
g1wp3 setWaypointType "MOVE";
g1wp3 setWaypointStatements ["true", "IPheloAS = false;"];

waitUntil{(!IPheloAS) or (!alive _AShelo1)};
if(!IPheloAS)then{_man groupChat localize "STR_HELODON";}else{_man groupChat localize "STR_HELODIE";};
if(alive _AShelo1)then{deleteVehicle _AShelo1;};

IPheloAS = false;
if(alive _pilot1)then{deleteVehicle _pilot1};
if(alive _pilot2)then{deleteVehicle _pilot2};
if(alive _pilot3)then{deleteVehicle _pilot3};
if(alive _pilot4)then{deleteVehicle _pilot4};
deleteMarkerLocal "asloc";
deleteMarkerLocal "asloc2";
deleteVehicle _lz1;
deleteVehicle _lz2;

landed = false;

[color="Red"]if(true)exitwith{as0 = _man addAction [localize "STR_MENUASM","airSup\addMenu.sqf",[], 5, false, false, "", "_target == player"];};[/color]

Bascially i want to add an action menu item inbetween the map click for the pickup point and the insertion point, this should cancel the script. Once the script is cancelled, it needs to be initialised again by adding the highlighted bit at the bottom, as the script would if run through to completion.

I hope that is understandable, thankyou in advance for any help.

Share this post


Link to post
Share on other sites

I'd be tempted to split it into three scripts. One for pickup, one for cancel and one for drop off. Keep track of what stage you're at with a variable on the player. Have all three actions always on the player but use conditions to only display when appropriate.

Share this post


Link to post
Share on other sites

Is there not a simple way to just exit an .sqf script at any point?

If i was using .sqs i would be tempted just to use "goto" then send it back to the top of the script on the action press. But i'm not sure how i would go about this in .sqf

Honestly i dont have the scripting knowledge to split this into three and as it is part of a much bigger script system, i'm not sure how this would work.

On a different subject Kylania while your about, did you get my PM regarding your "Search Body" script and use in a Dedicated MP enviroment. I am using both that and your POW script, but both seem only suited to SP.

Edited by Shadow.D. ^BOB^

Share this post


Link to post
Share on other sites

First off, the script isn't waiting where you have your "insert action here" comment; it's waiting at the waitUntil statement 10 lines down, so you would need to have your interrupt statement below that. Secondly, addAction works via executing a script, so you will need a new script that the action calls. That script should be very simple and look like this:

cancelAction = true;
ASclick = true;

Now, in your original script, all you need to do is put the following line immediately below the waitUntil statement:

if (cancelAction) exitWith {cancelAction = false;as0 = _man addAction [localize "STR_MENUASM","airSup\addMenu.sqf",[], 5, false, false, "", "_target == player"]};

Bear in mind that none of this will work properly in MP because of the local nature of addAction scripts.

Share this post


Link to post
Share on other sites

The waituntil you mention 10 lines below Dux is the script waiting until an insertion LZ has been selected, there is also a waituntil above which is the pickup LZ.

The problem i have is that if by mistake the person calling the script chooses a pickup LZ far away from the intended position (lets say they click the insertion point by mistake), there is no way to reset the script bar running to wherever it is and continuing as normal.

If this mistake is made at the start of a mission, its not a big deal, restart and go again. But i'm using the script system to simulate multiple pickups and insertions "LZ Hopping". So obviously if this mistake is made later in the mission, then it pretty much ruins your day, and makes the script system useless from then on.

This is something i've come across while testing and if i'm going to release missions using this then i really want to make them as foolproof as possible.

Edited by Shadow.D. ^BOB^

Share this post


Link to post
Share on other sites

I understand. My instructions were meant to achieve the goal you just described.

Share this post


Link to post
Share on other sites

Thats ok mate i appreciate any input, they all help me to understand bit by bit. Its hard to describe sometimes exactly what you need to achieve.

Thanks for taking the time.

Share this post


Link to post
Share on other sites
Is there not a simple way to just exit an .sqf script at any point?

Sure:

//init
_doexit = false;
//somewhere in a {} scope, do
_doexit = if(condition) then {true};
//outside the {} scope, do
if(_doexit) exitWith {};

If i was using .sqs i would be tempted just to use "goto" then send it back to the top of the script on the action press. But i'm not sure how i would go about this in .sqf

You can set a scopeName, and perform breakOut and breakTo commands to simulate goto. But that is really bad style.

I'm a bit too tired to try to understand the script, but if I read it correctly, I wouldn't bother with an action but instead do this when action that starts the script is executed:

1) Do the script.

2) Force open the map.

3) Wait for first click OR dialog/display closed.

4) If display closed, exit from main scope.

5) Wait for second click or dialog/display closed.

6) If display closed, exit from main scope.

7) All good? Continue with execution.

Using custom dialogs enables you to check using !dialog. For pure map based without any riffraff, you could try check using !visibleMap.

Lines I'm using in a script:

waitUntil {d_ari_fire || !dialog || !alive player};

deleteMarkerLocal "arti1_marker_1";
if (!alive player) exitWith {if (dialog) then {closeDialog 0}};
//Dialog closed.

if (d_ari_fire) then { /*the main part of the script*/ };

If you're desperate about using actions, you can create execution and cancel action at the same time, just controlling when they are shown, and removing both upon main execution.

Edit: Oh I didn't see this one...

The problem i have is that if by mistake the person calling the script chooses a pickup LZ far away from the intended position (lets say they click the insertion point by mistake), there is no way to reset the script bar running to wherever it is and continuing as normal.

You could do something like (a bit verbose, untested, but you get the idea):

_referencepoint = ?; //Need to be defined
_maxdistance = ?; //Need to be defined
_posok = false;
_doexit = false;
_clickpos = [];
openMap true; //or openMap [true,false];
while {!_posok && !_doexit} do {
onMapSingleClick {_clickpos = _pos};
waitUntil {!visibleMap || !alive player || count _clickpos > 0};
if (!alive player || !visibleMap) then {
	_doexit = true;
} else {
	_posok = if (_clickpos distance _referencepoint < _maxdistance) then {true};
};
if (_doexit) exitWith {}; //Exits only the while loop, not the script!
}; //while loop should restart at this point if clicked point was too far from intended point.
if (_doexit) exitWith {}; //This one should exit the script.
hint "Clicked point accepted";
/*
The remainer of the script that actually does stuff, in here

*/

Edited by CarlGustaffa

Share this post


Link to post
Share on other sites

Ok so if using that method CarlGustaffa, you could say have the reference point as the player calling the script (atm this is done by the unit name s1).

Then only when you select a pickup point lets say within 500m of the s1 player, the script will continue and allow you to select a insertion point?

Have i understood his correctly? The action menu thing was not something definate i wanted, basically any method that would stop a "mistake" from happening. If i have understood your method, it sounds like it could be just what i'm looking for.

Share this post


Link to post
Share on other sites

That was the intent, yes. In the event of script exiting, you should consider a hint or globalChat. Again, I didn't test it, so prone to both syntax and flow errors. But the idea is to waitUntil several conditions that could be trapped, and then execute on those traps individually.

Share this post


Link to post
Share on other sites

Ok thank, i will try and figure out how to incorporate that in. As i mentioned earlier i'm not very advanced with this stuff, so it may take me a while. :p

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  

×