Jump to content
Sign in to follow this  
celery

EasyFly script

Recommended Posts

I wrote this script to make fixed-wing flying less frustrating in my future releases but in the meantime everyone is welcome to use it as well.

In all its simplicity all it does is remove some of the inertia by smoothly transferring the plane's movement vector closer to where the nose is pointing.

Effects:

- Rudder has much more authority

- Precision movement such as aiming is easier

- The plane is generally more maneuverable

- The plane is less prone to stalling

- Stalls are easier to recover

Example video:

This script makes especially the Camel and A-10 nicer to fly as their infamous stalling problems are dampened and generally less inertia makes everything more simple. New aerobatic tricks are made possible because the rudder is more powerful than before.

Test mission:

http://selleri.pp.fi/arma/easyfly.zip

Make the player execVM this script at the start of the mission and nothing else is required.

easyfly.sqf (recommended)

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">//EasyFly script by Celery, SQF conversion by i0n0s

//Used to simplify fixed wing flight models

//

//Smaller _inertiaxy and _inertiaz values decrease inertia

//_stall is speed in km/h: script stops working at lower speeds

while {true} do {

  private ["_inertiaxy", "_inertiaz", "_stall", "_plane", "_velms"];

  waituntil {sleep 1;(vehicle player iskindof "Plane") and (alive player)};

  _plane = vehicle player;

  _inertiaxy = 7;

  _inertiaz = 4;

  if (_plane iskindof "Camel") then {_stall = 40} else {_stall = 150};

  while {(player == driver _plane) and (damage _plane < 1)} do {

      sleep 0.04;

      if (speed _plane >= _stall) then {

          _velms = (speed _plane) / 3.6;

          _plane setvelocity [

              (((vectordir _plane select 0) * _velms) + ((velocity _plane select 0) * _inertiaxy)) / (_inertiaxy + 1),

              (((vectordir _plane select 1) * _velms) + ((velocity _plane select 1) * _inertiaxy)) / (_inertiaxy + 1),

              (((vectordir _plane select 2) * _velms) + ((velocity _plane select 2) * _inertiaz)) / (_inertiaz + 1)

          ];

      };

  };

};

For historical purposes, the original SQS version:

easyfly.sqs

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">;EasyFly script by Celery

;Used to simplify fixed wing flight models

;

;Smaller _inertiaxy and _inertiaz values decrease inertia

;_stall is speed in km/h: script stops working at lower speeds

#start

~1

?vehicle player iskindof "Plane":goto "plane"

goto "start"

#plane

_plane=vehicle player

_inertiaxy=4

_inertiaz=7

_stall=150

?_plane iskindof "Camel":_stall=40

#loop

~0.04

?player!=driver _plane or !alive player:goto "start"

?speed _plane<_stall:goto "loop"

velms=(speed _plane)/3.6

_plane setvelocity [(((vectordir _plane select 0)*velms)+((velocity _plane select 0)*_inertiaxy))/(_inertiaxy+1),(((vectordir _plane select 1)*velms)+((velocity _plane select 1)*_inertiaxy))/(_inertiaxy+1),(((vectordir _plane select 2)*velms)+((velocity _plane select 2)*_inertiaz))/(_inertiaz+1)]

goto "loop"

Share this post


Link to post
Share on other sites

Excellent m8 been waiting for something like this for the Camel.... am trying it now thnx... yay.gif

Share this post


Link to post
Share on other sites

Any comments about how it works?

I've noticed that the script's performance heavily depends on the CPU. The heavier locations on Sahrani cause the script to lose its power on my low-grade PC but I'm not sure how it works on better computers.

Anyway, could someone please make a quick SQF conversion of the script as I'm a bit lost in that department? I'd like to see how the different formats perform. The 0.04 sec wait is important.

Share this post


Link to post
Share on other sites

Not tested, but should work:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">//EasyFly script by Celery;

//Used to simplify fixed wing flight models

//

//Smaller _inertiaxy and _inertiaz values decrease inertia

//_stall is speed in km/h: script stops working at lower speeds

while {true} do {

   private ["_inertiaxy", "_inertiaz", "_stall", "_plane", "_velms"];

   

   while {!(vehicle player iskindof "Plane")} do {

       sleep 1;

   };

   _plane = vehicle player;

   _inertiaxy = 4;

   _inertiaz = 7;

   if (_plane iskindof "Camel") then {

       _stall = 40;

   } else {

       _stall = 150;

   };

   while {(_plane == vehicle player) and (alive player)} do {

       sleep 0.04;

       if (speed _plane >= _stall) then {

           _velms = (speed _plane) / 3.6;

           _plane setvelocity [

               (((vectordir _plane select 0) * _velms) + ((velocity _plane select 0) * _inertiaxy)) / (_inertiaxy + 1),

               (((vectordir _plane select 1) * _velms) + ((velocity _plane select 1) * _inertiaxy)) / (_inertiaxy + 1),

               (((vectordir _plane select 2) * _velms) + ((velocity _plane select 2) * _inertiaz)) / (_inertiaz + 1)

           ];

       };

   };

};

Share this post


Link to post
Share on other sites

Thank you very much! SQF seems to handle the job much smoother. The SQF version created very heavy lag upon death but I fixed it with an alive check.

The SQF version has been added to original post.  smile_o.gif

Share this post


Link to post
Share on other sites

ok works fine for what i needed it for on the Camel....big improvemnt to the handling of it....Is there anyway to give the Camel a little bit more oomph!! smile_o.gif

Share this post


Link to post
Share on other sites

I have been playing with both the sqs and the sqf versions,would like someone else to confirm if they can that the sqs seems to run and perform way better in the camel...What difference could this really make as i am no mechanic i am simply a driver... smile_o.gif

Share this post


Link to post
Share on other sites

if i read the sqf version correct it isnt the same.

the sqs has a wait for player == alive

while the sqf has while(true) NO wait for player == alive

of course the missing sleep will make the while body processed every frame.

ps: even i0n0s' version is different to the first post's version.

Both need a sleep for the main loop (while(true)).

ps: you may want to use do .. for if you need unlimited runtime of the script. while has limit at 10k i think

Share this post


Link to post
Share on other sites

Just replace

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

while {!(vehicle player iskindof "Plane") or !(alive player)} do {

     sleep 1;

 };

with

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

waitUntil {sleep 0.532;vehicle player isKindOf "Plane"};

And while... is ok, the 10K limit was removed some time ago.

There was another small bug in the sqf version, _stall wasn't defined.

Complete version again:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

//EasyFly script by Celery;

//Used to simplify fixed wing flight models

//

//Smaller _inertiaxy and _inertiaz values decrease inertia

//_stall is speed in km/h: script stops working at lower speeds

while {true} do {

  waitUntil {sleep 0.532;vehicle player isKindOf "Plane"};

  _plane = vehicle player;

  _inertiaxy = 4;

  _inertiaz = 7;

  _stall = (if (_plane iskindof "Camel") then {40} else {150});

  while {(_plane == vehicle player) && (alive player)} do {

      sleep 0.04;

      if (speed _plane >= _stall) then {

          _velms = (speed _plane) / 3.6;

          _plane setvelocity [

              (((vectordir _plane select 0) * _velms) + ((velocity _plane select 0) * _inertiaxy)) / (_inertiaxy + 1),

              (((vectordir _plane select 1) * _velms) + ((velocity _plane select 1) * _inertiaxy)) / (_inertiaxy + 1),

              (((vectordir _plane select 2) * _velms) + ((velocity _plane select 2) * _inertiaz)) / (_inertiaz + 1)

          ];

      };

  };

waitUntil {alive player};

};

Xeno

Share this post


Link to post
Share on other sites

_stall is defined:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> if (_plane iskindof "Camel") then {

_stall = 40;

} else {

_stall = 150;

};

in combination with the private.

Share this post


Link to post
Share on other sites

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

waitUntil {sleep 0.532;vehicle player isKindOf "Plane"};

umm! sleep is not a condition. so putting sleep in in a waituntil command is kinda pointless

Share this post


Link to post
Share on other sites

umm! sleep is not a condition. so putting sleep in in a waituntil command is kinda pointless

Ummm, nope its not smile_o.gif WaitUntil continually checks its status as often as it can. Putting sleep in there makes it less intensive... ie... less of a potential framerate hog.

Share this post


Link to post
Share on other sites
_stall is defined:

...

in combination with the private.

Yes, you are right. smile_o.gif

Xeno

Share this post


Link to post
Share on other sites

icemotoboy yes. you are right. i always been thinking it only needs to forfill a condition, So i looked up the mighty wiki.

i looked at the example on the waituntil command

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_i = 0; waitUntil {_i = _i + 1; _i >= 100}

running this will give you 100 about stratit away.

that made no sence to me.. its like saying _i=0+100

i also had to make a little test script to be sure tounge2.gif

Share this post


Link to post
Share on other sites

Okay, so how is the script best optimized? The one in the main post is already doing its job very well.

Share this post


Link to post
Share on other sites

i'll try my best. if anyone else see more optimazine, they can correct me..

first of all

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">  while {!(vehicle player iskindof "Plane") or !(alive player)} do {

     sleep 1;

 };

i dont see the need for this code.

if your dead why wait?

or if your not in the vehicle why wait?

instead.. make a init.sqf script and use a eventhandler getin that activates the mainscript.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

 if (_plane iskindof "Camel") then {

     _stall = 40;

 } else {

     _stall = 150;

 };

again. why check the same thise values ove and over again..

instead check this value only once.

and 3 while loop.

1 is enough in your case i think.

//init.sqf

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_unit = vehicle _this;

_unit addeventhandler["Getin",{easyfly = (_this select 0) execvm "easyfly.sqf";}];

_unit execvm "easyfly.sqf";

//easyfly.sqf

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">

_plane = vehicle player;

_inertiaxy = 4;

_inertiaz = 7;

if (_plane iskindof "Camel") then {

_stall = 40;

} else {

_stall = 150;

};

while {((alive _plane) && (vehicle player == _plane) && (_plane iskinfdof "Plane") )} do

{

sleep 0.04;

if (speed _plane >= _stall) then

{

_velms = (speed _plane) / 3.6;

_plane setvelocity

[

(((vectordir _plane select 0) * _velms) + ((velocity _plane select 0) * _inertiaxy)) / (_inertiaxy + 1),

(((vectordir _plane select 1) * _velms) + ((velocity _plane select 1) * _inertiaxy)) / (_inertiaxy + 1),

(((vectordir _plane select 2) * _velms) + ((velocity _plane select 2) * _inertiaz)) / (_inertiaz + 1)

];

};

};

altho i have not tested this.

Share this post


Link to post
Share on other sites

@nuxil

It's allways a question what kind of mission you want to make, MP or SP. For MP you have to deal with locality and the getin eventhandler may not be the best solution for MP (though you still can use it smile_o.gif )

Xeno

Share this post


Link to post
Share on other sites

heh i didnt say it was perfect tounge2.gif

In MP

Event handlers are persistent (i.e. they stay attached to a unit, even after it dies and respawns).

so it should not be a problem. as you only want to add the eventhandler to the vehicle not the player itself.

if you start the in the vehicle. easyfly.sqf is executed strait away.

+ the vehicle adds the eventhandler incase you exit and re-enter.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">vehicle _unit addeventhandler{bla}

oh i forgot to def _stall.

but then again ther is porbealy X numbers of ways to achive this..

Share this post


Link to post
Share on other sites

but then again ther is porbealy X numbers of ways to achive this..

That is what programming is all about... there are allways other (maybe better) solutions smile_o.gif

Xeno

Share this post


Link to post
Share on other sites

Okay, I tried different things and here is a new version of the script:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">while {true} do {

private ["_inertiaxy", "_inertiaz", "_stall", "_plane", "_velms"];

waituntil {sleep 1;(vehicle player iskindof "Plane") and (alive player)};

_plane = vehicle player;

_inertiaxy = 7;

_inertiaz = 4;

if (_plane iskindof "Camel") then {_stall = 40} else {_stall = 150};

while {(player == driver _plane) and (damage _plane < 1)} do {

sleep 0.04;

if (speed _plane >= _stall) then {

_velms = (speed _plane) / 3.6;

_plane setvelocity [

(((vectordir _plane select 0) * _velms) + ((velocity _plane select 0) * _inertiaxy)) / (_inertiaxy + 1),

(((vectordir _plane select 1) * _velms) + ((velocity _plane select 1) * _inertiaxy)) / (_inertiaxy + 1),

(((vectordir _plane select 2) * _velms) + ((velocity _plane select 2) * _inertiaz)) / (_inertiaz + 1)

];

};

};

};

Eventhandlers are not used because they can be heavy as well and having it executed with one single line that covers everything is much more simple. Alive checks and the likes are needed because at least I will use this script in respawn missions where the aircraft is created on the fly instead of placed in the editor. There were some minor errors in the original conversion (such as damage > 0) that I have corrected.

Share this post


Link to post
Share on other sites
Eventhandlers are not used because they can be heavy...

Heavy?  huh.gif

Having an eventhandler would mean the script doesn't have to run all the time for every plane. Better for performance. Instead of having, say, 10 instances for 10 planes the whole time, you would have 1 instance for 1 player in a plane and none when the player wasn't in a plane.

Quote[/b] ]and having it executed with one single line that covers everything is much more simple.

Eventhandler can also be added with one single line...

Although it's not a big deal, unless you were making it into a mod. It's still good to keep things optimised.

Share this post


Link to post
Share on other sites

When a plane is created with a script and the mission is all about flying it, anything else than executing the script once at the start of the mission would be masochism. And I doubt that this script will be used in missions where there is only a fleeting chance to fly a plane, not that a one second check loop would have any effect on the overall performance.

In any case, an advanced mission maker can modify scripts as he pleases, a simple way to use this one out of the box is a matter of convenience.

Share this post


Link to post
Share on other sites

Very much looking forward to your new map Celery xmas_o.gif

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  

×