Jump to content
Sign in to follow this  
Sokoloft

How to have a vehicle open it's door at a certain speed?

Recommended Posts

"passenger" <- there is no such thing, all passengers are "cargo"
Try changing the array to this, maybe the roles are uppercase:
["Cargo","Driver"]

 

I have a trigger named missionarea, does it need to be a marker or anything different?

A marker would also work, so that shouldn't make a difference.

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

  • Like 1

Share this post


Link to post
Share on other sites

I tried the above and still no success, any idea's?

nul = [this, missionarea, 5, ["Cargo","Driver"]] spawn fnc_autounload;

It isn't even triggering the the door's to open or anything, neither is it telling me if there is an error or not. Not sure if that's a good sign or not but I'm not sure were to go from here. Thanks for all the help!

 

PS: I don't have it in my init.sqf, instead it is it's own .sqf, called in the init by the following line, does that matter or not?

fnc_autounload = compileFinal preprocessFileLineNumbers "scripts\functions\fnc_autounload.sqf";

as well as it's still defining itself with fnc_autounload = {    does that matter? Let me know! Thanks!

Share this post


Link to post
Share on other sites

What's the difference in the way I call it? I would imagine another way to do it would be to make a sqf and call it functions.sqf, with each function defined via fnc_name = {   then execute it in my init.sqf via execVM??? Not sure, new to all of this so, let me know if it matters! Thanks again!

Share this post


Link to post
Share on other sites

"execVM" and "spawn" are almost the same, so you're right there.

 

 

"spawn" and "execVM" run asynchronous to the script that called them. They don't return anything (except for an id) and the parent-script will immediately continue with the next line of code, no matter what the spawned code does in the meantime.

 

"call" is different. The parent-script will wait for the call to complete and send back a result, before it continues.

 

 

 

Anything in the init has to be completed in one go before the actual mission starts. It can not sleep or wait.

  • Like 1

Share this post


Link to post
Share on other sites

Anything in the init has to be completed in one go before the actual mission starts. It can not sleep or wait.

Just to clear that up for Sokoloft, using spawn from init is OK if you need a sleep as it doesn't suspend the script itself.

The same applies to the debug console, if you need a sleep or a loop, you need to

_nul = [arguments] spawn {code};
  • Like 1

Share this post


Link to post
Share on other sites

Hey there! Thanks for the response, now from reading what you guys said, I'm taking it doesn't matter if I have the code in the init.sqf or have it defined in the init.sqf as the following, just to keep my init clean:

fnc_autounload = compileFinal preprocessFileLineNumbers "scripts\functions\fnc_autounload.sqf";

Even having the code @Tajin provided in the init.sqf still does the same thing, it doesn't throw any errors, do I just have it configured incorrectly? I have the following in my fnc_autounload.sqf

fnc_autounload = {
    params ["_vehicle", "_trigger", "_spd","_roles"];
    waitUntil {sleep 1; (speed _vehicle < _spd) && (_vehicle inArea _trigger)};
    _vehicle animate ["ramp_rotate",1];
    sleep 1;
    {
        if ((_x select 1) in _roles) then {
            _unit = _x select 0;
            unassignVehicle _unit;
            doGetOut _unit;
            _unit action ["Eject",_vehicle];
            sleep 0.5;
        };
    } forEach fullCrew _vehicle;
    waitUntil {sleep 1; (speed _vehicle > _spd)};
    _vehicle animate ["ramp_rotate",0];
};

is it due to it being defined twice by the fnc_autounload = {  ???   Not sure, might try that. Or should I have all of my functions in one .sqf and have each of them defined fnc_fncname = { then execVM the script in my init.sqf so there's 1 line instead of 4 via compileFinal??? Not sure, thanks so much guys! Slowly starting to understand this stuff :D

Share this post


Link to post
Share on other sites

Hmm that is a weird construct.... would lead to something like this:

fnc_autounload = {
	fnc_autounload = {
		... script ...
	}
}

I guess it would mean that the function only redefines itself the first time you run it and that you would have to run it a second time for the actual code to take effect...
The problem there beeing that compileFinal does not even allow the function to be changed afterwards... so it will just try to redefine itself and fail.
 
In other words: "Bad – don't do it!"
 
 
 
It's not that complicated if you understand what each command really does.
 
 
Functions are basically just variables that contain code.
You can define them directly.

fnc_something = {
    // somescript...
}

 
Or you can put the code in a separate file:

// somescript...

 
and then either execVM it directly:

0 = [parameters] execVM "somescript.sqf";

 
or you can read the contents of the file, which puts it into a string (and runs it through the preProcessor)

fnc_somescript = compile preprocessFileLineNumbers "scripts\functions\fnc_autounload.sqf";

then convert that string into code

fnc_somescript = compile preprocessFileLineNumbers "scripts\functions\fnc_autounload.sqf";

 

and then put that code into the variable that you want to use as function:

fnc_autounload = compileFinal preprocessFileLineNumbers "scripts\functions\fnc_autounload.sqf";

 

Essentially, that is almost the same as this:

fnc_something = {
    // somescript...
}

Except that, if you use compileFinal, the variable will also be protected and can not be changed anymore.
 
 
 
 
On a sidenote: If you really want to work with functions a lot and really like to keep it clean, then the best way is by using the Functions Library (which is the same way the vanilla functions are defined).
Essentially it means that you have a folder structure with 1 file per function and a config file in which they are listed.

  • Like 1

Share this post


Link to post
Share on other sites

Hey @Tajin thanks for the info, going to double and maybe even triple check that documentation during the course of the afternoon and when I can I'll start implementing it to my mission. Reading over it once indicates that this is the method that some of my other downloaded scripts like VVS or bons Inf recruit system use, and then is called via the #include option in my desc.ext if I make a cpp or hpp. Thanks again! Will post once I have any news!

Share this post


Link to post
Share on other sites

Hey! I got all my fnc's running via that method, so I can view all of my mission related fnc's via the fnc viewer. However it's being a bit weird to my other fncs, but I'll ask theend3r about that. Now back to trying to get units to disembark automatically, I got your bit of code to open the door! However, it doesn't have them get out, and so far I've only tested it to were the player drives it into the zone, but it should be the same for AI as well if they're the driver. Going to see now, but any idea's? Thanks!

 

PS: I also have multiple vehicles doing this, with a lot of AI getting out from them.

 

Edit

 

I let it go for a good maybe 20 minutes in the background, and the AI navigate the landing defences, and get to the point to were they open up the doors, however no one gets out :( How would we go about making it to were it's the vehicles model name? So if one spawns in via another script I have "VVS" It has the same things happen to it? Thanks so much man!

  • Like 1

Share this post


Link to post
Share on other sites

Since you apparently want everyone to get out, lets just remove the bit that checks for specific crew-roles. I guess this one causes problems.

fnc_autounload = {
    params ["_vehicle", "_trigger", "_spd","_roles"];
    waitUntil {sleep 1; (speed _vehicle < _spd) && (_vehicle inArea _trigger)};
    _vehicle animate ["ramp_rotate",1];
    sleep 1;
    {
        _unit = _x;
	leaveVehicle _unit;
	doGetOut _unit;
	_unit action ["Eject",_vehicle];
	sleep 0.5;
    } forEach crew _vehicle;
    waitUntil {sleep 1; (speed _vehicle > _spd)};
    _vehicle animate ["ramp_rotate",0];
};

If you want to make it dependant on classnames, use your trigger and put the following in the condition field (onAct is not needed):

{
	_vehicle = _x;
	if (typeOf _vehicle in ["classname1","classname2"]) then {
		if (_vehicle getVariable ["autounload",0] == 0) then {
			_vehicle setVariable ["autounload", [_vehicle, this] spawn fnc_autounload_trg ,true];
		};
	};
} forEach thisList;
this

fill in the array of classnames

Also define this function:

fnc_autounload_trg = {
	params ["_veh","_trigger"];
	while { _veh inArea _trigger} do {
		if ((_veh animationPhase "ramp_rotate") == 0) then {
			if (speed _veh < 5)	then {
				_veh animate ["ramp_rotate",1];
				sleep 1;
				{
					_unit = _x;
					leaveVehicle _unit;
					doGetOut _unit;
					_unit action ["Eject",_veh];
					sleep 0.5;
				} forEach crew _veh;
			};
		};
		if ((_veh animationPhase "ramp_rotate") == 1) then {
			if (speed _veh > 5)	then {
				_veh animate ["ramp_rotate",0];
			};
		};
		sleep 1;
	};
	_veh setVariable ["autounload",nil,true];
};

The way its set up you could also use that in several triggers (as long as they're not too close to each other and don't overlap)

Edited by Tajin
  • Like 1

Share this post


Link to post
Share on other sites

Well, as for the first solution fnc_autounload I couldn't get to work, says there is an error between the following line and the ending line

    } forEach crew _vehicle;

and

};

As for the second solution I tried first, I couldn't get the code to go into the on condition field, it said "Type nothing, expected bool"?? So a true or false some weres? Not sure, thanks for the info! Hope to hear from you soon!

Share this post


Link to post
Share on other sites

There, fixed the bug in my last post (first script) and added a return to the condition field (it just has to return something or arma will complain about it)

Share this post


Link to post
Share on other sites

Hey man, thanks for not forgetting about me! I tried fnc_autounload.sqf and I got a result, the AI disembarked, however they get slaughtered by both hostile MG's and the driver of  the boat itself, because sometimes the boats get caught up on coastal defenses, and the AI have to navigate there way in, it thinks that it has come to it's final resting point. So possibly a longer sleep between speed checks? Maybe a 10 second sleep, and as well as changing the speed to open the door to maybe like 2-3 kmh. As well as a stop command for the driver, so he doesn't run over friendly's disembarking.

 

As for the second method, I got the condition field entered and configured correctly. However when it goes to call it says there is an error on this line, missing )( someweres.

if ((_veh animationPhase "ramp_rotate") = 0) then {

Thanks so much again! Almost there for a pub release on my mission! Just need to configure ALiVE and other odds and ends like this! Hope to hear from you soon!

 

Edit: Any surviving AI try to return to the boat, is it possible to have a command to tell the AI to advance at a certain bearing? Going to look into the command, just don't know were to implement it, probably towards the end once they disembark? Not sure

Share this post


Link to post
Share on other sites

Just remove the linebreaks for the condition field.

{_vehicle = _x; if (typeOf _vehicle in ["classname1","classname2"]) then { if (_vehicle getVariable ["autounload",0] == 0) then { _vehicle setVariable ["autounload", [_vehicle, this] spawn fnc_autounload_trg ,true];	};};} forEach thisList; this

Share this post


Link to post
Share on other sites

Hey man, been busy the past couple days and haven't had time to look at the post. I tried that condition field, but I still get the error on the script on this line, says it's missing a ) and I'm not sure were, maybe you do?

if ((_veh animationPhase "ramp_rotate") = 0) then {

Thanks again, hope to hear from you soon!

Share this post


Link to post
Share on other sites
if ((_veh animationPhase "ramp_rotate") == 0) then {

you need == , not = as it's comparison, not assignation.

  • Like 1

Share this post


Link to post
Share on other sites

Hey das, I should of known that! I changed it however now I'm just getting more errors. Tried to fix it but yet again I don't know what I'm doing, maybe you can find were the error is, either that when @Tajin checks out the forum post he can look at it, but this is my fn_autounload_trg.sqf file:


	params ["_veh","_trigger"];
	while { _veh inArea _trigger} do {
		if ((_veh animationPhase "ramp_rotate") == 0) then {
			if (speed _veh < 5)	then {
				_veh animate ["ramp_rotate",1];
				sleep 1;
				{
					_unit = _x;
					unassignVehicle _unit;
					doGetOut _unit;
					_unit action ["Eject",_veh];
					sleep 0.5;
				} forEach crew _veh;
			};
		};
		if ((_veh animationPhase "ramp_rotate") == 1) then {
			if (speed _veh > 5)	then {
				_veh animate ["ramp_rotate",0];
			};
		};
		sleep 1;
	};
	_veh setVariable ["autounload",nil,true];

Thanks again!

 

Edit: Error generic error in expression?

Share this post


Link to post
Share on other sites

Edit: Error generic error in expression?

The error usually shows you where the problem is but when it doesnt, put a lot of debug messages (systemchat "Debug 1"; systemchat "Debug 2"; ...etc.) in the script and call it with execVM to know where the problem is.

Share this post


Link to post
Share on other sites

Hey @theend3r, I tried adding (systemchat "Debug 1";) after every line, however it will only do the last entry. Probably because it was past the ending }; idk tho, plus it only throws the error when the specific vehicle goes into the area. So if I execVM it just goes through, what should I do, this is what I've got:

fnc_autounload_trg = {
systemchat "Debug 1";
	params ["_veh","_trigger"];
	systemchat "Debug 2";
	while { _veh inArea _trigger} do {
	systemchat "Debug 3";
		if ((_veh animationPhase "ramp_rotate") == 0) then {
		systemchat "Debug 4";
			if (speed _veh < 5)	then {
			systemchat "Debug 5";
				_veh animate ["ramp_rotate",1];
				systemchat "Debug 6";
				sleep 1;
				systemchat "Debug 7";
				{
					_unit = _x;
					systemchat "Debug 8";
					unassignVehicle _unit;
					systemchat "Debug 9";
					doGetOut _unit;
					systemchat "Debug 10";
					_unit action ["Eject",_veh];
					systemchat "Debug 11";
					sleep 0.5;
					systemchat "Debug 12";
				} forEach crew _veh;
				systemchat "Debug 13";
			};
		};
		if ((_veh animationPhase "ramp_rotate") == 1) then {
		systemchat "Debug 14";
			if (speed _veh > 5)	then {
			systemchat "Debug 15";
				_veh animate ["ramp_rotate",0];
				systemchat "Debug 16";
			};
		};
		sleep 1;
		systemchat "Debug 17";
	};
	_veh setVariable ["autounload",nil,true];
	systemchat "Debug 18";
};
systemchat "Debug END";

Let me know were I went wrong! Thanks!

Share this post


Link to post
Share on other sites

Hey @theend3r, I tried adding (systemchat "Debug 1";) after every line, however it will only do the last entry. Probably because it was past the ending }; idk tho, plus it only throws the error when the specific vehicle goes into the area. So if I execVM it just goes through, what should I do, this is what I've got:

Let me know were I went wrong! Thanks!

You didn't exec the function at all, you just defined it, that's why you only got the last one.

Also, I did say "a lot" but I didn't mean after every line. :D

 

Just put the vehicle in the area and spawn the function like you did originally (but with the debug chat lines). You should know where it stops.

 

Edit: Maybe forEach doesn't accept sleep? I think it should but I'm not sure. It should work.

Share this post


Link to post
Share on other sites

So, this is the error that pops up in the black box, really don't know what I'm doing >_<

 

w0t_zpsepqyn2dl.jpg

 

Not sure what to do, let me know! Will check back tomorrow when I feel better.

Share this post


Link to post
Share on other sites

I think it would need extra brackets

if ((_vehicle getVariable ["autounload",0]) == 0) then {

Share this post


Link to post
Share on other sites

Based on that info, I re did the trigger on condition since I don't see getVariable in the script

 {_vehicle = _x; if (typeOf _vehicle in ["CLASSNAMEHERE"]) then { if ((_vehicle getVariable ["autounload",0]) == 0) then { _vehicle setVariable ["autounload", [_vehicle, this] spawn fnc_autounload_trg ,true]; };};} forEach thisList; this 

However I still get an error:

 

error1_zpsryfvgduz.jpg

 

Thanks :D

Share this post


Link to post
Share on other sites
{

 _vehicle = _x;

 if ((typeOf _vehicle) == "CLASSNAMEHERE") then {

	if ((_vehicle getVariable "autounload") == 0) then {

		_vehicle setVariable ["autounload", [_vehicle, thisTrigger] call fnc_autounload_trg ,true];

	};
};

} forEach thisList;

You cant set spawn as variable value because spawn is not allowing  passing back function calculations, script handle only.

Use call instead, and if you want refer to the trigger where the code is executed use thisTrigger not this

Share this post


Link to post
Share on other sites
if ((_veh animationPhase "ramp_rotate") == 0) then {
you need == , not = as it's comparison, not assignation.

 

Ew, seems like I did a rookie-mistake there. :wacko: Shame on me. :D

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  

×