Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Discussion: Flight Assist

Dioxide DeSantis
Registered User
Join date: 2 Feb 2007
Posts: 63
08-28-2007 20:32
Not sure if I have an outdated code or what. For some reason I don't hover at all.
If I stop flying I start to go down immediately I am only at 500m
But here is what I am using right now.

// Flight Assist Example
//
// Highlights:
// - altitude-based assist (lower altitude == less assist, higher == more)
// - horizontal movement gets relatively less assist than vertical.
// - HUD color indication of movement mode
// - brown: not flying (i.e. earth)
// - green: flying w/ assist
// - white: hovering w/ assist
// - black: assist disabled


// gAssistParams enables altitude-based flight assist. Lower altitudes
// will get less momentum assist so that the client updating overhead
// is less likely to harm controllability. Plus it's a pain to collide
// with a building at high speed in a damage-enabled area.
//
// see increaseMomentumAssist() for more info
//
list gAssistParams = [ <1.1, 100, 200>, <1.25, 100, 800>, <1.4, 1000, -1> ];
float gInc = 0.1; // The increment to add to the momentum assist parameter on the next control key event
float gMass; // current mass (assuming it's constant; can imagine a variable mass assist tho :-) )
integer gMotor = FALSE; // Indicates whether momentum assistance is on
integer gAgentInfo; // A bitmask of the agent/avi current state
integer gReqKeys; // A bitmask of the control keys required to operate
integer gReqPerms; // A bitmask of the required permissions to operate
key gWearer; // UUID of the avi who is wearing this attachment

float gMomentumAssist = 0; // The current applied momentum assist
float increaseMomentumAssist(vector pos)
{
integer iii;
integer len;

len = llGetListLength(gAssistParams);
vector aParams;
for (iii = 0; iii < len; iii++)
{
aParams = llList2Vector(gAssistParams, iii);
if (pos.z < aParams.z)
{
jump exitLoop;
}
}
@exitLoop;

if (gMomentumAssist < aParams.y)
{
gInc *= aParams.x; // increase momentum assist exponentially
// param values closer to 1 result in slower growth
gMomentumAssist += gInc;
}
else
{
gMomentumAssist = aParams.y;
}

return gMomentumAssist;
}

vector getForwardDir()
{
vector ret;

ret = <1,0,0>*llGetCameraRot(); // camera rotation leads forward direction; so use it to direct assist
ret.z = 0;

return llVecNorm(ret);
}

getPermissions()
{
if ((llGetPermissions() & gReqPerms) == gReqPerms)
{
llTakeControls(gReqKeys, TRUE, TRUE);
}
else
{
llRequestPermissions(gWearer, gReqPerms);
}
}

gotControlInput(integer held)
{
gAgentInfo = llGetAgentInfo(gWearer);

if (!(held & gReqKeys))
{
if (gAgentInfo & AGENT_FLYING)
{
state hover;
}
}

if (gAgentInfo & AGENT_FLYING)
{
if (held & gReqKeys)
{
vector p = llGetPos();
vector dir;
float assist;

assist = increaseMomentumAssist(p);

if (p.z > llGround(ZERO_VECTOR)+50.0)
{
llSetBuoyancy(1.0);
}
else
{
// For some reason, if you are below
// llGround()+50.0 meters, you will
// slowly rise to that height if you
// llSetBuoyancy(1.0). An avatar can maintain
// hover below this height w/o assist; so
// no buoyancy change.
llSetBuoyancy(0.0);
}

if (held & CONTROL_FWD)
{
dir = getForwardDir();
// flying too fast horizontally
// typically makes the avatar
// uncontrollable since lag is
// high due to heavy updates;
// Do a simple reduction of assist
assist /= 3.0;
}
else if (held & CONTROL_BACK)
{
dir = -getForwardDir();
assist /= 3.0;
}
else if (held & CONTROL_UP)
{
dir = <0,0,1>;
}
else if (held & CONTROL_DOWN)
{

dir = <0,0,-1>;
}

llPushObject(gWearer, assist*gMass*dir, ZERO_VECTOR, FALSE);

gMotor = TRUE;
}
}
}

onAttach(key avatar)
{
gWearer = avatar;
if (gWearer != NULL_KEY)
{
getPermissions();
}
}

default
{
state_entry()
{
gReqKeys = CONTROL_FWD | CONTROL_UP | CONTROL_DOWN | CONTROL_BACK;
gReqPerms = PERMISSION_TRACK_CAMERA|PERMISSION_TAKE_CONTROLS;
gMass = llGetMass();
llSetColor(<0,1,0>, ALL_SIDES);

// Check if HUD is already attached
gWearer = llGetOwner(); // for now
if (llGetAttached() != 0)
{
getPermissions();
}

llSetTimerEvent(0.1);
}

on_rez(integer param)
{
llResetScript();
}

attach(key agent)
{
onAttach(agent);
}

run_time_permissions(integer perm)
{
if (perm & PERMISSION_TAKE_CONTROLS)
{
llTakeControls(gReqKeys, TRUE, TRUE);
}
}

touch_start(integer num)
{
state disabled;
}

control(key owner, integer held, integer change)
{
gotControlInput(held);
}

timer()
{
gAgentInfo = llGetAgentInfo(gWearer);

if (!(gAgentInfo & AGENT_FLYING))
{
state landed;
}
}
}

state hover
{
state_entry()
{
llSetColor(<1,1,1>, ALL_SIDES);

gMotor = FALSE;
gMomentumAssist = 0;
gInc = 0.1;
// adjust a little for lag
llMoveToTarget(llGetPos(), 0.1);
vector pos = llGetPos();
// you can hover unassisted at ground level + 50 meters
// in fact, if you set buoyancy to 1.0 there, you will slowly
// rise to ground level + 50 meters
if (llGround(ZERO_VECTOR)+50.0 < pos.z)
{
llSetBuoyancy(1.0);
}
else
{
llSetBuoyancy(0.0);
}

llTakeControls(gReqKeys, TRUE, TRUE);
}

changed(integer what)
{
if (what & CHANGED_REGION)
{
state landed;
}
}

on_rez(integer param)
{
llResetScript();
}

at_target(integer number, vector curPos, vector targPos)
{
llStopMoveToTarget();
}

control(key owner, integer held, integer change)
{
gotControlInput(held);

state default;
}

touch_start(integer num)
{
state disabled;
}

state_exit()
{
llStopMoveToTarget();
}
}


state landed
{
state_entry()
{
llStopMoveToTarget(); // just in case
llSetBuoyancy(0.0);
llSetColor(<0.5,0.5,0.25>, ALL_SIDES);
llSetTimerEvent(0.3);
}

on_rez(integer param)
{
llResetScript();
}

attach(key agent)
{
onAttach(agent);
}

run_time_permissions(integer perm)
{
if (perm & PERMISSION_TAKE_CONTROLS)
{
llTakeControls(gReqKeys, TRUE, TRUE);
}
}

touch_start(integer num)
{
state disabled;
}

timer()
{
gAgentInfo = llGetAgentInfo(gWearer);

if (gAgentInfo & AGENT_FLYING)
{
state default;
}
}
}

state disabled
{
state_entry()
{
llSetBuoyancy(0.0);
llStopMoveToTarget(); // just in case
llSetColor(<0,0,0>, ALL_SIDES);
}

attach(key agent)
{
onAttach(agent);
}

run_time_permissions(integer perm)
{
if (perm & PERMISSION_TAKE_CONTROLS)
{
llTakeControls(gReqKeys, TRUE, TRUE);
}
}

on_rez(integer param)
{
llResetScript();
}

touch_start(integer num)
{
state landed;
}
}
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
08-28-2007 20:43
I copied and pasted from what you posted and it works fine. I went up to 20,000 meters and hovered in place and dropped back down to 200 meters and hovered. The prim changed colors per the script.

#1 Are you wearing it? It can be worn on your person or attached to the screen. It needs to be worn so that it can get permissions?

#2 Is the script in the root prim? I will not work in a child prim.

#3 Is the script running and is the prim changing colors per state?
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Dioxide DeSantis
Registered User
Join date: 2 Feb 2007
Posts: 63
08-28-2007 21:32
From: Jesse Barnett
I copied and pasted from what you posted and it works fine. I went up to 20,000 meters and hovered in place and dropped back down to 200 meters and hovered. The prim changed colors per the script.

#1 Are you wearing it? It can be worn on your person or attached to the screen. It needs to be worn so that it can get permissions?

#2 Is the script in the root prim? I will not work in a child prim.

#3 Is the script running and is the prim changing colors per state?


I attach it to the hud with a single prim and yes the colors changed as i moved maybe if I try putting it into a new prim so I am starting from scratch.

Ill let you know if that works
Dioxide DeSantis
Registered User
Join date: 2 Feb 2007
Posts: 63
08-28-2007 21:51
Ok well it worked great once I used a new object SL gotta love it.

Thanks for the help
Anya Ristow
Vengeance Studio
Join date: 21 Sep 2006
Posts: 1,243
09-11-2007 03:33
I had the same trouble Dioxide had. It wasn't working, so I put the script into a brand new prim and then it worked. But I learned a little more than that...

If you make any change to the script and re-save it, even a null-change (hit the space bar, hit backspace, save the script) it will no longer work. To fix it, you don't have to create a new prim; you just have to detatch and re-attach.

Resetting the script does not cause this same problem.
Anya Ristow
Vengeance Studio
Join date: 21 Sep 2006
Posts: 1,243
09-11-2007 14:52
Some things I've learned...

All of the flight assist scripts I have allow way too much drift after releasing the forward/backward control, except this one. This one stops the avatar dead in its tracks with the llMoveToTarget call in the hover state. Very nice, except that the avatar twists to the side. It works nicely for control, but looks really awful. I can't figure out how to stop this twisting. I've tried llStopLookAt, because what I think is happening is that the avatar is trying to face the new target, and I've tried zeroing the torque. Neither works.

Also I've discovered that all these scripts make the avatar difficult to control because even a zero-force push launches the avatar into motion. There is no way to apply a small force to get a small motion. Very unfortunate. [1]

Also, I don't know how much of a difference it makes, but increaseMomentumAssist does a whole lot of processing every time a control event happens. This script is a lot more jerky than my other flight assist scripts, even in low-lag private sims, and I think this might be why. I'd test a fix, but probably wouldn't choose this script over the others without a fix to the avatar twisting, anyway.

[1] Edit: On further reflection and testing I've determined that it is the standard avatar movement that causes this large motion, since this script passes control events on. A zero force push probably adds nothing to the movement. I tested this by entering flight mode at a high elevation (which doesn't allow me to climb but does set me hovering/skimming). I get the same large movement at high altitude that I do without any flight assist.
Anya Ristow
Vengeance Studio
Join date: 21 Sep 2006
Posts: 1,243
09-26-2007 03:52
I ended up writing my own flight assist script, but I did use llMoveToTarget in the hover state, as you did. The comment in your script says this compensates for lag, but what it really does is kill your momentum. I'm going to call it Momentum Arrest. I still wish I could do it without the avatar jerking about. It'll be a feature that can be turned off.
Luc Aubret
Oreo-eater
Join date: 14 Sep 2005
Posts: 86
02-14-2008 00:25
I'd like to make some minor suggestions to try, nothing as formal as a repost of the script.

1. Instead of llMoveToTarget(llGetPos(),0.1), why not llMoveToTarget(llGetPos()+(llGetVel()*0.1),0.1)? What's causing the av torque is the fact that it's determining the pos an instant before moving to it, so you're actually going back a few meters. By adding a slight factor for velocity to adjust to the lag, I think you can still stop pretty darn quick without the avatar doing that ugly mid-air turn.

2. The way this script is formatted, you can't fly on certain planes simultaneously. For instance, if you press W and C (forward and down), you'll either fly forward OR down, and not both. Instead, what if you removed the "else"s, and allowed it to run the "if"s for each directional arrow (in the increaseMomentumAssist function). Then instead of doing a direction = whatever for each arrow, do direction += whatever, so that it's adding the info from each planar movement to the overall direction generated by the function?

Again, I'm making these suggestions just by reading, and have not tested any of these. Just thought they might clear up some issues.
Anya Ristow
Vengeance Studio
Join date: 21 Sep 2006
Posts: 1,243
02-14-2008 02:12
From: Luc Aubret
1. Instead of llMoveToTarget(llGetPos(),0.1), why not llMoveToTarget(llGetPos()+(llGetVel()*0.1),0.1)?


I tried this and found that it caused a "trying to push through" effect when you collide with things and release the keys. Also, if I recall, it didn't eliminate the twisting unless you left a lot of slack, which though better than without any momentum arrest at all was still less desirable than the precision of an immediate stop. I don't remember, though, if I experimented with this with the low boost levels that I'm now using. It deserves another visit.

My script has a different force calculation than the posted script so we may get different results. It's worth trying on that script, too.

From: someone
2. The way this script is formatted, you can't fly on certain planes simultaneously. For instance, if you press W and C (forward and down), you'll either fly forward OR down, and not both.


I often use forward and turn, but it never occured to me to try forward and up (or down). I'll bet my script has this same limitation. [Tries it] Yep, it does!

Thanks!
Anya Ristow
Vengeance Studio
Join date: 21 Sep 2006
Posts: 1,243
02-14-2008 02:21
From: Anya Ristow
still less desirable than the precision of an immediate stop


Maybe I can make this an adjustable setting, like the adjustable boost level. Just tried it and yep, I'm still getting the "trying to push through" effect when I collide with things. I think I'm finding that it does that, anyway, depending on the thickness of the object and your speed, so maybe I should just ignore it. I'll do some more testing.
Anya Ristow
Vengeance Studio
Join date: 21 Sep 2006
Posts: 1,243
02-14-2008 20:46
I worked some more with the velocity adjustment for the llMoveToTarget and didn't like it. It makes the trying-to-push-through effect on collisions worse. You can fix this by putting an llStopMoveToTarget on a collision event, but that also allows you to bounce off things.

I made a change to allow simultaneous movement controls, and I've sent you a copy.
Wicc Cunningham
Registered User
Join date: 25 Jun 2004
Posts: 52
02-09-2009 18:28
I've noticed one thing in trying out this script. If I turn off flight I stick in place. If I tap any movement key I do start to drop. I don't know if that is as intended or not. Otherwise it works great. I do recall something like this happening with an anti-push script but I don't recall what was done to keep that from happening.

I did try removing the buoyancy statements in the hover state. Changing or removing these didn't seem to make a difference.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
02-09-2009 19:42
From: Wicc Cunningham
I've noticed one thing in trying out this script. If I turn off flight I stick in place. If I tap any movement key I do start to drop. I don't know if that is as intended or not. Otherwise it works great. I do recall something like this happening with an anti-push script but I don't recall what was done to keep that from happening.

I did try removing the buoyancy statements in the hover state. Changing or removing these didn't seem to make a difference.

An old thread but a good thread:)
With no direct knowledge of the backend.....................
I have always thought of this as you are "invisible" to the server, or it pays you no attention, whatever you want to call it, until you move again.

And yes this is a great script, I changed a couple of things for my own use but it is still the script I use today. Just because I have always been curious, I have tried umpteen jillion free and paid flight assists and this one is still the best in my book.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Wicc Cunningham
Registered User
Join date: 25 Jun 2004
Posts: 52
02-10-2009 18:52
From: Wicc Cunningham
I've noticed one thing in trying out this script. If I turn off flight I stick in place. If I tap any movement key I do start to drop. I don't know if that is as intended or not. Otherwise it works great. I do recall something like this happening with an anti-push script but I don't recall what was done to keep that from happening.

I did try removing the buoyancy statements in the hover state. Changing or removing these didn't seem to make a difference.


Ah-ha!! I figured out what would do it tonight. I just modified the hover state to have a timer event, check to see if the agent is flying, if not then call the landed state. As shown in the snippet below.

CODE

state hover
{
state_entry()
{
llSetColor(<1,1,1>, ALL_SIDES);

gMotor = FALSE;
gMomentumAssist = 0;
gInc = 0.1;
// adjust a little for lag
llMoveToTarget(llGetPos(), 0.1);
vector pos = llGetPos();
// you can hover unassisted at ground level + 50 meters
// in fact, if you set buoyancy to 1.0 there, you will slowly
// rise to ground level + 50 meters
if (llGround(ZERO_VECTOR)+50.0 < pos.z)
{
llSetBuoyancy(1.0);
}
else
{
llSetBuoyancy(0.0);
}

llTakeControls(gReqKeys, TRUE, TRUE);
llSetTimerEvent(0.1);
}

on_rez(integer param)
{
llResetScript();
}

at_target(integer number, vector curPos, vector targPos)
{
llStopMoveToTarget();
}

control(key owner, integer held, integer change)
{
gotControlInput(held);

state default;
}

touch_start(integer num)
{
state disabled;
}

timer()
{
gAgentInfo = llGetAgentInfo(gWearer);

if (!(gAgentInfo & AGENT_FLYING))
{
state landed;
}
}

state_exit()
{
llStopMoveToTarget();
}
}
1 2