/*

Keyframe Wanderer - Randomly wander where the ground is above water using keyframe motion

This can be used to make an animesh animal that wanders randomly over the ground.

The example used here is a wolf. Change the animations and sounds to match your animal.

*/


float water;
float ground;

vector regionSize;
integer isOn;
float tick;

string oAnim;

anim( string an)
{
    
        llStopObjectAnimation(oAnim);
        oAnim = an;
        llStartObjectAnimation(oAnim);
        
}

rotate(vector move, float ang)
{
    list kf;
    float time = 2; // how long to rotate 
        
    kf += move;
    kf += llEuler2Rot(<0.0,0, ang>);
    kf += time; 

    
    if (move == ZERO_VECTOR) anim("wolfsniff"); // Animation to play when rotating in place (on region edge or water edge)
    else anim("wolfwalk");// Animation to play while walking and rotating in place 
    
    llSetKeyframedMotion( kf, [KFM_DATA, KFM_TRANSLATION|KFM_ROTATION, KFM_MODE, KFM_FORWARD]);
    llSetTimerEvent(time + 0.1);
}


default
{
    on_rez(integer n)
    {
        llResetScript();
    }
    
    state_entry()
    {
         list curr_anims = llGetObjectAnimationNames();
        integer length = llGetListLength(curr_anims);
        while (--length>=0)
        {
            llStopObjectAnimation(llList2String(curr_anims, length));
        }
        
       
        regionSize = osGetRegionSize();
        water = llWater(ZERO_VECTOR);

 
        llSay(0, "Touch me to activate. I will go where the ground is above water. ");
        llSetKeyframedMotion([], []);
        
        llListen(0, "", "", "wolf come"); // Shouting "wolf come" will bring the wolf near you. Change  it to whatever call you want to use
    }
    
    
    listen(integer chan, string w, key id, string msg)
    {
        {

            list userData=llGetObjectDetails(id, [OBJECT_NAME,OBJECT_POS, OBJECT_ROT]);
            llSetKeyframedMotion([], []);

            vector v = llList2Vector(userData, 1);
            vector size  = llGetAgentSize(id);
            llSetRegionPos( v + <1, 0,-size.z/2 + 0.25>*llList2Rot(userData,2) );
            llSetTimerEvent(1*isOn);

        }
    }
    
    
    touch_start(integer n) 
    {
        isOn=!isOn;
        llSetKeyframedMotion([], []);
        llSetTimerEvent(1*isOn);
        llSay(0,"Active="+(string)isOn);
    }
    
    
    timer()
    {
        llSetKeyframedMotion([], []);
        
        // Do something randomly
        integer rnd = (integer)llFrand(5);
        if (rnd ==1)
        {
            // Stay idle
            if (llFrand(1) < 0.5)
            {
                // Howl
                llTriggerSound("howl", 1); 
                anim("wolfsniff");
            }
            else
            {
                //just stand
                anim("wolfidle");
            }
            llSetTimerEvent(3+llFrand(6));
        }
        else if (rnd ==2)
        {
            // rotate randomly
            vector v = llRot2Euler(llGetRot());
            v.x =0; 
            v.y =0;
            vector fwd = <1,0,0>*llEuler2Rot(v);
            rotate(fwd, 0.3 + llFrand(1));
        }
        else
        {
            // Try to move forward by 3 meters
            vector v = llRot2Euler(llGetRot());
            v.x =0; 
            v.y =0;
            
            vector pos = llGetPos();        
            vector fwd = <1,0,0>*llEuler2Rot(v);

            float ang = 0.3+llFrand(0.3);
            
            vector nxt   = llGetPos() + 3*fwd;
            float grnd = llGround(3*fwd);
            
            if (grnd <= water
            || nxt.x <=3 || nxt.x >= regionSize.x-3
            || nxt.y <=3 || nxt.y >= regionSize.y-3
            )
            {
                rotate(ZERO_VECTOR, 1.0);
                return;
            }
            
            nxt.z = grnd + 0.8; // Change the distance of the animesh from the ground
            
            list kf ;
            
            float time = 3.0; // Change the time  to change speed
            
            vector dist = (nxt - llGetPos());
            
            kf += dist; 
            kf += ZERO_ROTATION; 
            kf += time;
            
            anim("wolfwalk");
            llSetKeyframedMotion( kf, [KFM_DATA, KFM_TRANSLATION|KFM_ROTATION, KFM_MODE, KFM_FORWARD]);
            llSetTimerEvent(time+0.1);
        }
    }
}