// From the book:
//
// Scripting Recipes for Second Life
// by Jeff Heaton (Encog Dod in SL)
// ISBN: 160439000X
// Copyright 2007 by Heaton Research, Inc.
//
// This script may be freely copied and modified so long as this header
// remains unmodified.
//
// For more information about this book visit the following web site:
//
// http://www.heatonresearch.com/articles/series/22/

          
               ////////Script upgrated by MatieuBC Noel since July 28 2008 ////////// See my freebie at www.slexchange.com searsh by my name to find my product          
integer channel2 =-2340;
integer channel = -3161 ; 
displayChute()
{
 llSay(channel,"off");   //Invert the on and off to show the parachut to mofify it easilly
}
displayChute2()
{
 llSay(channel,"on");   
}
integer calculateGroundDistance()
{
    vector pos = llGetPos();
    float ground = llGround(pos);
    float distance = llRound(pos.z-ground);
    return (integer)distance;
}


default
{
  
     attach(key AvatarKey)
    {
        if(AvatarKey)
        {//event is called on both attach and detach, but Key is only valid on attach
            integer test = llGetAttached();
            if (test) {
                llOwnerSay( "The object is attached" );
            
            } else {
                llOwnerSay( "The object is not attached");
            
            }
        }
    }

 attach(key id)
    {
        if(id)
        {
            state attached;
       
         }
    }
}


state attached
{
    state_entry()
    {
        llSetText("", <1, 1, 1>, 1);
        displayChute();
        llSetTimerEvent(1);
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
        llPreloadSound( "parachute" );
           
    
    }
    
    attach(key id)
    {
        if(id==NULL_KEY)
        {
            state default;
       
        }
    }

    timer()
    {
        if(  (llGetAgentInfo(llGetOwner()) & AGENT_IN_AIR) && 
            !(llGetAgentInfo(llGetOwner()) & AGENT_FLYING) ) //The ! before the line mean that the avatar are not flying.
        {
            state falling;
        }
      
   
     } 
}

state falling
{
    state_entry()
    {
      llSetTimerEvent(1);
        llStopAnimation("falldown");
         llListen( -2341, "", NULL_KEY, "" ); //HUD channel to  open parachute
        llStartAnimation("fall");
     
     }
    
    timer()
    {
        integer dist = calculateGroundDistance(); //Absolutly necesary to add timer(). This line stop the animation fall at specific altitude.
        
        if( (dist<30) && (dist>0) )
        llStopAnimation("fall");
       
  }

listen( integer channel, string name, key id, string message )
{
 if ( message == "L" ) 
    {llStopAnimation("fall");
        state deployed;   
      
    }

 }
    
    attach(key id)
    {
        if(id==NULL_KEY)
        {
            state default;
        }
    }
}

state deployed  //State mean that the parachute is open phase
{
    state_entry()
    {
        llTriggerSound("parachute",1);
        displayChute2();
        llSetTimerEvent(0.01);
        llStopAnimation("fall");
        llStartAnimation("pose");
        
    }
    
    timer()
    {
        // on the ground
        if (    !(llGetAgentInfo(llGetOwner()) & AGENT_IN_AIR) && 
            !(llGetAgentInfo(llGetOwner()) & AGENT_FLYING) ) 
        {
            llStopAnimation("pose");   
              llStopAnimation("fall");
           llStartAnimation("landing");
            llSay(channel2,"O");   //say on a specific channel number O to the HUD to change color
             state attached;
             
             llResetScript();
        
        }
        
        // started flying
        if( llGetAgentInfo(llGetOwner()) & AGENT_FLYING) 
        {   
            llStopAnimation("fall");
            llStopAnimation("pose");
           state attached;
           llStopAnimation("landing");
           llResetScript();
        }

        vector v = llGetVel();  //vector v = the wind vector by default
        if( v.z < -7 )     //v.z is the code that isolate the z axis. So Y and Z is not count
        {
            llPushObject(llGetOwner(), <0,0,3>, v , TRUE);
            }
    } 
    
    attach(key id)
    {
        if(id==NULL_KEY)
        {
             llStopAnimation("fall");
            llStopAnimation("pose");
            state default;
             llResetScript();
         }
    }

 
 

 }
 
 
 
 