Jump to content
Sign in to follow this  
LtShadow

New flyby script, I need your help! :) Switches and Cases

Recommended Posts

Hey community,

I have a question in regards to Switch events within ArmA.

I know how they work, on a basic scale, but I need to know how to implement them into the script available with the @REALSOUND FA-18 Super Hornet I released.

Here is a look at what I am working at;

Whole script (currently I am not testing this till I get the idea of what I need to do, so don't worry about the conflicting code. (this also includes me trying to implement a case/switch system)

private "_flyby";

_flyby = false;

while {alive _this} do {
_sleeptime = 19;
while {!_flyby} do {
	sleep 2;
	_dist = player distance _this;
	_speed = speed _this;
	_ex = ((_this != vehicle player) && !(vehicle player isKindOf "Plane"));
	//_a10 = (_this isKindOf "A10" || _this isKindOf "Su25_base");
	//_su = (_this isKindOf "Su34" || _this isKindOf "ACE_T10" || _this isKindOf "L39_TK_EP1" || _this isKindOf "ACE_Su30"  || _this isKindOf "ACE_Su34");
	//_av8 = (_this isKindOf "F18C");

	if (_dist > 180 && _dist <= 1000 && (_speed > 350) &&  _ex) exitWith {
		playsound3D "close_fb";
		_flyby = true;


	};

	comment "Checking speed and distance for sound file.";
	_speed2 = (_dist > 180 && _dist <= 1000 && (_speed > 350));
	switch (_speed2) do 
	{ 
	case (_dist > 180 && _dist <= 1000 && (_speed > 350)):
	{
	playsound "close_fb";
	_flyby = true;
	};


};		


};
sleep _sleeptime;
_flyby = false;
};

More specifically, I wish to implement a case in which it checks for the plane's distance and speed like the above IF statement.

So, if it is one speed play a sound, if it is another play that sound instead.

Ideas? Thoughts? Comments?

Thank ya! :)

Best regards,

Shadow

p.s.

BigPickle is working with me on it, but I thought posting here would help speed up the process.

Share this post


Link to post
Share on other sites

Any help at all would be much appreciated! :)

Share this post


Link to post
Share on other sites

I find switches are best when simple. Use if statements (nested if need be) to determine a condition.

_case = if ((speed _vehicle) > 100) then {
if ((_vehicle distance _unit > 100) then {a} else {b};
} else {
if ((_vehicle distance _unit > 100) then {c} else {d};
};

switch (_case) do {
case a: {
// code for Distance and speed over 100
};
case b: {
// code for speed over 100, distance less than 100
};
case c: {
// code for speed less than 100, distance over 100
};
case d: {
// code for speed and distance under 100
};
};

Share this post


Link to post
Share on other sites

So it would look something like this then, right?

_vehicle = (_this select 0)
_unit = player

_case = if ((speed _vehicle) > 100) then {
if ((_vehicle distance _unit > 100) then {a} else {b};
} else {
if ((_vehicle distance _unit > 100) then {c} else {d};
};
switch (_case) do {
case a: {
if (_dist > 100 && _dist <= 1000 $$ (_speed > 100))
playsound "close_fb";
_flyby = true
// code for Distance and speed over 100
};
case b: {
if (_dist < 100 $$ (_speed < 100))
playsound "close_fb";
_flyby = true
// code for speed over 100, distance less than 100
};
case c: {
if (_dist > 100 && _dist <= 1000 $$ (_speed < 100))
playsound "close_fb";
_flyby = true
// code for speed less than 100, distance over 100
};
case d: {
if (_dist < 100 $$ (_speed <= 100))
playsound "close_fb";
_flyby = true
// code for speed and distance under 100
};
};  

I have a good idea on how I need to do this, but could you show me how I can define these variables specifically FOR this aircraft, so not all aircraft will play the sound file if they are going fast enough?

Also, how can I get the sound files to play if they are not just 100 meters... i.g. All aircaft flyby sounds are not going to be played within just 100 meters, how can I change them to be more specific? :)

Thank you!

Best Regards,

Shadow

Share this post


Link to post
Share on other sites

you need to add this to the init eventhandler (class) of your aircraft, after that _this select 0 will be the aircraft.

so use _aircraft = _this select 0; at the start of the script.

try say3D to play sound in the 3D space.

Share this post


Link to post
Share on other sites
you need to add this to the init eventhandler (class) of your aircraft, after that _this select 0 will be the aircraft.

so use _aircraft = _this select 0; at the start of the script.

try say3D to play sound in the 3D space.

Right, well I need to get the actual script working first before I get into the possible ways of relaying the audio. ;)

Anyone else? :)

Share this post


Link to post
Share on other sites
whats the problem then?

Trying to get the game to play a number of sound files depending on the aircraft and it's speed/distance from the player.

Share this post


Link to post
Share on other sites

I have a good idea on how I need to do this, but could you show me how I can define these variables specifically FOR this aircraft, so not all aircraft will play the sound file if they are going fast enough?

It depends on how you call the script. At the top of your script, you have "_vehicle = (_this select 0)". This is a variable sent to the script.

0 = [VehicleName] execVM "scriptName.sqf";

See the VehicleName in the brackets? That is "_this select 0". The variable sent to the script becomes a "_this select #". For example, look at:

0 = [VehicleName, UnitName, Distance, Speed] execVM "scriptName.sqf";

"_this select 0" is VehicleName

"_this select 1" is UnitName

"_this select 2" is Distance

"_this select 3" is Speed

See the pattern?

So, when the script starts, you see "_vehicle = _this select 0;", but the game see's "_vehicle = VehicleName;". The pattern continues for all the variables sent to the script.

Also, how can I get the sound files to play if they are not just 100 meters... i.g. All aircaft flyby sounds are not going to be played within just 100 meters, how can I change them to be more specific? :)

You would have to use more if/then statements. Your format above is wrong. You have left out then "then" and "else" ("else" not required) in your statements. You have "if (_dist < 100 $$ (_speed < 100))" and that is it. That will fail. You need to complete the statement. "if (_dist < 100 && (_speed < 100)) then {playsound "1"} else {playsound "2"}".

There are many more things wrong with your script. Here is a list of what I see, quickly looking.

1. "_dist" is not defined. That is a local variable that has no meaning at the moment. You would need "_dist = player distance _vehicle;" to be called before "_dist" later.

2. "_speed" is not defined. See #1. "_speed = speed _vehicle;"

3. You are missing many ";" (semi-colons) at the end of your lines. Your script would fail at line 1.

4. You have "$$" in a few places instead of "&&".

5. You are missing the "then" in your "if" statements. See above.

6. Your conditions are conflicting within your "switch".

case a: {
if (_dist > 100 && _dist <= 1000 $$ (_speed > 100))
playsound "close_fb";
_flyby = true
// code for Distance and speed over 100 

See the above statement from your post. I commented "// code for Distance and speed over 100", then you added an extra "if (_dist > 100 && _dist <= 1000 $$ (_speed > 100))". Speed and distance over 100 have already been discovered. That's why it is case "a". A second "if" statement is useless there. Also, look at "_dist > 100 && _dist <= 1000". That pretty much says "if distance is over 100, and if distance is over 1000". Well, if distance is over 1000, then for sure it is over 100. Its (again) useless to have there. Then "(_speed > 100)"; speed has already been discovered to be over 100, that's why it is case "a". To use what I posted, you have to define statements BETWEEN what I have already done. Second statements saying the same thing are unneeded.

_vehicle = _this select 0; // <-- no "()" needed, but ";" required
_unit = player;


_dist = _vehicle distance _unit; // <-- Define "_dist"
_speed = speed _vehicle; // <-- Define "_speed"

_case = if (_speed > 100) then {
if ((_dist > 100) then {a} else {b};
} else {
if ((_dist > 100) then {c} else {d};
};

switch (_case) do {
case a: { // <-- code for Distance and speed over 100
if (_dist < 200) then { // <-- now that distance/speed are over 100, what about 200. "if distance is less than (<) 200 THEN "playsound1" ELSE (if over 200) "playsound2";"
playsound "distance100-200";
} else {
playsound "NoSound"; // <-- over 200m from player. "playsound "NoSound";" would not work. I just used that as an example to explain things.
};
};
case b: {
// code for speed over 100, distance less than 100
};
case c: {
// code for speed less than 100, distance over 100
};
case d: {
// code for speed and distance under 100
};
};  

Look at switch "a". Speed and distance have already been defined by "_case". In this case, both are over 100. So, again I use an "If" statement. If distance is less than 200, then play sound "distance100-200" ELSE (if distance is over 200) then playsound "NoSound" aka nothing. That's how you would nest more "if" statements into a switch.

Share this post


Link to post
Share on other sites

Thank you for that very educated response! :D I can see it definitely took some time out of your day, so thank you again first of all.

Second:

What if the _dist is less than 200, but the speed is less than or equal to 300? Does the same example apply, but with the speed? Since _speed is already defined, would this be contradictory?

E.g.

case b: {
if (_dist < 200 && _speed <= 300) then { // <-- speed is less than 300 - distance is less than 200, now playsound
playsound "flyby"
} else {
playsound "NoSound"; // <-- Example - change to Exit
};
}; 
}; 

Thanks again,

:)

Share this post


Link to post
Share on other sites

Again, still looking for a working solution! :3 Keep em coming guys, really appreciate the responses!

Share this post


Link to post
Share on other sites

I'm gonna have to rewrite most of what I posted to accommodate all that you want. Give me a list of what scenarios (speed & distance) you want covered and I'll write the switch/if statements accordingly.

The reason I say this is because I had 100 as the base speed. Considering we are talking about jets, 100 should be one of the lesser speeds instead.

Share this post


Link to post
Share on other sites
I'm gonna have to rewrite most of what I posted to accommodate all that you want. Give me a list of what scenarios (speed & distance) you want covered and I'll write the switch/if statements accordingly.

The reason I say this is because I had 100 as the base speed. Considering we are talking about jets, 100 should be one of the lesser speeds instead.

Alright, thank you! :)

Okay, I'm at work on my phone ATM so excuse any grammar issues.

So basically:

If aircraft is less than 200 dist and speed is more than 300 play sound file 1

If aircraft is less than 100 meters and speed more than 400 play sound file 2

If aircraft less than 500 meters out, but greater than 200 and speed is above 300 play sound file 3

And then, I wish for it to be editable to the best ability on my end to correctly adjust the sound files I have.

Could you also include comments so I can learn from your work? Your name will be listed on the credit roll for my aircraft configs from here on out. :)

Again, thank you so much for your help!

Shadow

Share this post


Link to post
Share on other sites

You listed very specific scenarios with a lot of gaps between them. I filled them in with different sound files for now. The switch, as it turns out, is not needed at all. You can just use nested IF statements to play the sound. To me, adding a switch would be extra clutter and CPU usage. But I could see where it might make things easier to edit down the line. I'll post both shortly.

Without Switch:

// Speed and Distance for Sound for LtShadow
// By Fight9

// <200 dist, >300 speed, file 1
// <100 dist, >400 speed, file 2
// <500 >200 dist, >300, file 3

_vehicle = _this select 0;
_unit = player;

_dist = _vehicle distance _unit;
_speed = speed _vehicle;

if (_dist < 200) then { // if dist is under 200 then
if (_dist > 100) { // if distance is over 100 so 100-200
	if (_speed > 300) then { // if speed is over 300
		playSound "file1a"; // over 100 dist, over 300 speed
	} else { // if speed is under 300
		playsound "file1b"; // over 100 dist, under 300 speed
	};
} else { // if dist is under 100 - so 0-100
	if (_speed > 400) then { // if speed is over 400
		playSound "file2a"; // under 100 dist, over 400 speed
	} else { // if speed is under 400
		playsound "file2b"; // under 100 dist, under 400 speed
	};
};
} else { // if dist is over 200
if (_dist < 500) then { // if under 500, but wont hit if under 200 - so 200-500 dist
	if (_speed > 300) then { // if soeed is over 300
		playSound "file3a"; // 200-500 dist, over 300 speed
	} else { // if speed is under 300
		playSound "file3b"; // 200-500 dist, under 300 speed
	};
};
};

With Switch:

// Speed and Distance for Sound for LtShadow w/ switch
// By Fight9

// <200 dist, >300 speed, file 1
// <100 dist, >400 speed, file 2
// <500 >200 dist, >300, file 3

_vehicle = _this select 0;
_unit = player;

_dist = _vehicle distance _unit;
_speed = speed _vehicle;

_case = if (_dist < 200) then { // if dist is under 200 then
if (_dist > 100) { // if distance is over 100 so 100-200
	if (_speed > 300) then { // if speed is over 300
		1a; // over 100 dist, over 300 speed
	} else { // if speed is under 300
		1b; // over 100 dist, under 300 speed
	};
} else { // if dist is under 100 - so 0-100
	if (_speed > 400) then { // if speed is over 400
		2a; // under 100 dist, over 400 speed
	} else { // if speed is under 400
		2b; // under 100 dist, under 400 speed
	};
};
} else { // if dist is over 200
if (_dist < 500) then { // if under 500, but wont hit if under 200 - so 200-500 dist
	if (_speed > 300) then { // if soeed is over 300
		3a; // 200-500 dist, over 300 speed
	} else { // if speed is under 300
		3b; // 200-500 dist, under 300 speed
	};
};
};

switch (_case) do {
case 1a: {playSound "file1a";}; // over 100 dist, over 300 speed
case 1b: {playsound "file1b";}; // over 100 dist, under 300 speed
case 2a: {playSound "file2a";}; // under 100 dist, over 400 speed
case 2b: {playsound "file2b";}; // under 100 dist, under 400 speed
case 3a: {playSound "file3a";}; // 200-500 dist, over 300 speed
case 3b: {playSound "file3b";}; // 200-500 dist, under 300 speed
};

I wrote it in my editor this time instead of directly in the forums. That's why you see the indented formatting. It makes things a lot easier to read and I should have done that from the start.

Edited by Fight9

Share this post


Link to post
Share on other sites

Awesome work mate, thanks a bunch. Will try it soon!

As for calling it in game; how would I go about doing so? Just calling for it under my init line in the config like it already is?

E.G.

		class Eventhandlers : Eventhandlers {
		init = "(_this select 0) execVM ""\f4phantom_rs\scripts\init1.sqf"";";
	};

Share this post


Link to post
Share on other sites

Assuming the script works at all, that would be it.

I kind of think it will only work once and then stop. Might have to add a while loop to it. That eats a lot of resources though. There has got to be a better way. Have you considered looking into how JSRS or SoundMod do their scripting?

Share this post


Link to post
Share on other sites

I was thinking something like the original, like this;

private "_flyby";

_flyby = false;

while {alive _this} do {
_sleeptime = 19;
while {!_flyby} do {
	sleep 2;
	_dist = player distance _this;
	_speed = speed _this;
	_ex = ((_this != vehicle player) && !(vehicle player isKindOf "Plane"));
              _vehicle = _this select 0;
              _unit = player;

	if (_dist < 200) then { // if dist is under 200 then
		if (_dist > 100) { // if distance is over 100 so 100-200
			if (_speed > 300) then { // if speed is over 300
				playSound "file1a"; // over 100 dist, over 300 speed
       } else { // if speed is under 300
           playsound "file1b"; // over 100 dist, under 300 speed
       };
   } else { // if dist is under 100 - so 0-100
       if (_speed > 400) then { // if speed is over 400
           playSound "file2a"; // under 100 dist, over 400 speed
       } else { // if speed is under 400
           playsound "file2b"; // under 100 dist, under 400 speed
       };
   };
} else { // if dist is over 200
   if (_dist < 500) then { // if under 500, but wont hit if under 200 - so 200-500 dist
       if (_speed > 300) then { // if soeed is over 300
           playSound "file3a"; // 200-500 dist, over 300 speed
       } else { // if speed is under 300
           playSound "file3b"; // 200-500 dist, under 300 speed
       };
   };
sleep _sleeptime;
_flyby = false;
};
};
};  

Something along the lines of that.

Share this post


Link to post
Share on other sites

That might work. I'll look at it later tonight when I get home to make sure you don't have any extra brackets at the end. It kind of looks like you do but I won't know until I put it into Notepad++. That's one of the greatest features of that editing program; it tells you where brackets open and close.

Share this post


Link to post
Share on other sites

Here you go. I cleaned up the formatting a bit and changed a few things to help performance. The inner while wont start until the vehicle is within 500m. I removed the "_flyby = false;" since there was no condition that resulted in it being true. I changed it to "_startDist = 500;". It definable at the top along with the sleep/refresh time. I removed the "_vehicle", and the "_unit", and "_ex". Since you are only sending one variable to the script (the aircraft), that becomes "_this", which you have already changed. The "_ex" variable wasn't being used at all and wasn't doing anything. What it was checking for was whether the player was not in the aircraft ("_this") and is not in any sort of airplane. Its a little redundant but I trust that's what you wanted. "_unit" and "_vehicle" were also no longer needed since they were not being used. I moved the "_sleepTime" to outside of the last if condition. Before it would have only hit if the aircraft was over 200m away. I added a small sleep to the outer while loop to help performance a tad.

Well, here it is.

// init = "(_this select 0) execVM ""\f4phantom_rs\scripts\init1.sqf"";"; 

private ["_sleeptime","_startDist","_start","_dist","_speed"];

_sleepTime = 19;
_startDist = 500;

while {alive _this} do {
_start = player distance _this;
   while {(_start <= _startDist) && (_this != vehicle player) && !(vehicle player isKindOf "Plane")} do {
       _dist = player distance _this;
       _speed = speed _this;
       if (_dist < 200) then { // if dist is under 200 then
           if (_dist > 100) { // if distance is over 100 so 100-200
               if (_speed > 300) then { // if speed is over 300
                   playSound "file1a"; // over 100 dist, over 300 speed
			} else { // if speed is under 300
				playsound "file1b"; // over 100 dist, under 300 speed
			};
		} else { // if dist is under 100 - so 0-100
			if (_speed > 400) then { // if speed is over 400
				playSound "file2a"; // under 100 dist, over 400 speed
			} else { // if speed is under 400
				playsound "file2b"; // under 100 dist, under 400 speed
			};
		};
	} else { // if dist is over 200
		if (_dist < 500) then { // if under 500, but wont hit if under 200 - so 200-500 dist
			if (_speed > 300) then { // if soeed is over 300
				playSound "file3a"; // 200-500 dist, over 300 speed
			} else { // if speed is under 300
				playSound "file3b"; // 200-500 dist, under 300 speed
			};
		};
	};
	sleep _sleepTime;
};
sleep 5;
};

Share this post


Link to post
Share on other sites
Here you go. I cleaned up the formatting a bit and changed a few things to help performance. The inner while wont start until the vehicle is within 500m. I removed the "_flyby = false;" since there was no condition that resulted in it being true. I changed it to "_startDist = 500;". It definable at the top along with the sleep/refresh time. I removed the "_vehicle", and the "_unit", and "_ex". Since you are only sending one variable to the script (the aircraft), that becomes "_this", which you have already changed. The "_ex" variable wasn't being used at all and wasn't doing anything. What it was checking for was whether the player was not in the aircraft ("_this") and is not in any sort of airplane. Its a little redundant but I trust that's what you wanted. "_unit" and "_vehicle" were also no longer needed since they were not being used. I moved the "_sleepTime" to outside of the last if condition. Before it would have only hit if the aircraft was over 200m away. I added a small sleep to the outer while loop to help performance a tad.

Well, here it is.

// init = "(_this select 0) execVM ""\f4phantom_rs\scripts\init1.sqf"";"; 

private ["_sleeptime","_startDist","_start","_dist","_speed"];

_sleepTime = 19;
_startDist = 500;

while {alive _this} do {
_start = player distance _this;
   while {(_start <= _startDist) && (_this != vehicle player) && !(vehicle player isKindOf "Plane")} do {
       _dist = player distance _this;
       _speed = speed _this;
       if (_dist < 200) then { // if dist is under 200 then
           if (_dist > 100) { // if distance is over 100 so 100-200
               if (_speed > 300) then { // if speed is over 300
                   playSound "file1a"; // over 100 dist, over 300 speed
			} else { // if speed is under 300
				playsound "file1b"; // over 100 dist, under 300 speed
			};
		} else { // if dist is under 100 - so 0-100
			if (_speed > 400) then { // if speed is over 400
				playSound "file2a"; // under 100 dist, over 400 speed
			} else { // if speed is under 400
				playsound "file2b"; // under 100 dist, under 400 speed
			};
		};
	} else { // if dist is over 200
		if (_dist < 500) then { // if under 500, but wont hit if under 200 - so 200-500 dist
			if (_speed > 300) then { // if soeed is over 300
				playSound "file3a"; // 200-500 dist, over 300 speed
			} else { // if speed is under 300
				playSound "file3b"; // 200-500 dist, under 300 speed
			};
		};
	};
	sleep _sleepTime;
};
sleep 5;
};

Thanks for that!

I will try it later after church today. :)

Best Regards,

Shadow

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  

×