Project:

Back to project

File name: Tram.lsl
Code: View Raw Code
integer channel = -94531;
integer report_channel = -94530;

integer direction;
integer curPoint;
list points;
string route;
integer nextStation =-1;

integer isPaused;

float OFFSET=0;


float SPEED = 3.75; //meters /second


vector INITROTATION=<0,0,PI/2>;


float WATERHEIGHT = 20.05;


list messages;
list delays;
list messageTimes;
integer curMessage;

beginRoute(list points)
{
            llSetKeyframedMotion( [], []);
            //llSetRot(ZERO_ROTATION);
            llSleep(0.3);
            
            messageTimes = [];
            curMessage = 0;
            
            OFFSET=(float)llGetObjectDesc();
         
         
            vector pos = llList2Vector(points,0);
            llSetRegionPos(pos);
            llSetRot(llEuler2Rot(INITROTATION));
            
            rotation rot = llEuler2Rot(INITROTATION);
            integer i;            
            list kf;
            float totTime =0;
            messageTimes = [];

            for (i=0; i < llGetListLength(points); i++)
            {
                vector v = llList2Vector(points, i);
                rotation r2  = llEuler2Rot(INITROTATION);
                if (i < llGetListLength(points)-1)
                {
                    vector vn = llVecNorm(llList2Vector(points, i+1) - v);
                    
                    // break rotation in 2 parts: along Z, then along the rest. llRotBetween would turn the train upside-down
                    vector v2 = vn;
                    v2.z =0;
                    rotation r2a = llRotBetween(<1,0,0>, v2);      // Rotation along the Z axis only
                    rotation r2b = llRotBetween(<1,0,0>*r2a, vn);  
                                        
                    r2 = r2a*r2b; //llRotBetween(<1,0,0>,vn);
                }
                else
                {
                    r2 = rot;
                    //v.y -= OFFSET; // boat Parking offset
                }
                
                vector cor = llRot2Euler(r2);
                if (cor.x == -PI)
                    cor.x = PI;
                //cor.x=0; // Remove any rotation around X
                r2 = llEuler2Rot(cor);
                    
                
                float t;
                if (i>0)
                {
                        
                    kf += (1.0)*(v-pos);
                    kf += ZERO_ROTATION;
                    t = llVecMag(v-pos)/SPEED; //adjust for speed
                    kf += t*(1.0);
                                

                    
                    
                    rotation myrot = llRotBetween(<1,0,0>*rot, <1,0,0>*r2);

                    kf += ZERO_VECTOR ;
                    kf += r2 / rot; // myrot; //llEuler2Rot(<0,cor.y,0>);
                    kf += .5;
                    
                    
                    
                }
                else // the zero-th frame is just a rotation
                {
                    kf += ZERO_VECTOR;
                    kf += (r2/rot);
                    kf += 2; //adjust for speed
                    t = 2;
                }
                
                
                kf += ZERO_VECTOR;
                kf += ZERO_ROTATION;
                
                float delay = llList2Float(delays, i);
                kf += delay; //adjust for speed
                t +=  delay;
                
                totTime+= t;
                
                pos = v;
                rot = r2;

                messageTimes += (t+1 );
            }
            

            //llLoopSound("paddle", 1.0);
            llSetKeyframedMotion( kf, [KFM_DATA, KFM_TRANSLATION|KFM_ROTATION, KFM_MODE, KFM_LOOP]);
    
            llMessageLinked(LINK_SET, 0, "START", "");
            llStopSound();
            llSleep(.1);
            llLoopSound("train", 1.);
}


doStop()
{
            isPaused = !isPaused;
            
            if (isPaused)
                llSetKeyframedMotion( [], [KFM_COMMAND, KFM_CMD_PAUSE]);
            else
                llSetKeyframedMotion( [], [KFM_COMMAND, KFM_CMD_PLAY]);

            if (isPaused)            
            {
                llMessageLinked(LINK_SET, 0, "STOP", "");
                llStopSound();
            }
            else
            {
                llMessageLinked(LINK_SET, 0, "START", "");
                llLoopSound("train", 1.);
            }
                        

}



default
{
    state_entry()
    {
        llSitTarget(ZERO_VECTOR, ZERO_ROTATION);
        llListen(channel,"", "","");
        llMessageLinked(LINK_SET, 0, "STOP", "");
    }
    
    listen(integer chan, string n, key sender, string cmd)
    {

        
        if (cmd  == "Pause/Cont")
        {
            doStop();
        }
        else if (cmd == "PANIC")
        {
            llSetKeyframedMotion([], []);
            llStopSound();
            llSetTimerEvent(0);
        }
        else if (cmd == "Reset11")
        {
            list lines = llParseString2List(osGetNotecard("route"), ["\n"], []);
            integer j=0;
            {
                list tk = llParseString2List(llList2String(lines,j), ["|"], []);
                vector p= llList2Vector(tk,0);
               // llSay( 0, (string)p);
                llSetRegionPos(p);
                llSetRot( llEuler2Rot(INITROTATION));
            }
        }
        else if (cmd == "Reset")
        { 
            list lines = llParseString2List(osGetNotecard("route"), ["\n"], []);
            integer j;
            points = [];
            delays = [];
            messages = [];
            for (j=0; j < llGetListLength(lines); j++)
            {
                list tk = llParseString2List(llList2String(lines,j), ["|"], []);
                points += llList2Vector(tk,0);
                delays += llList2Float(tk,1);
                messages += llList2String(tk,2);
            }
            beginRoute(points);
            llSetTimerEvent(5);
        }
    }
    
    touch_start(integer n)
    {
        if (llDetectedKey(0) == llGetOwner())
            llDialog(llDetectedKey(0), "Select", ["Reset", "Pause/Cont", "PANIC", "CLOSE"], channel);
    }
    
     
    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            integer i;
            for (i=2; i < llGetNumberOfPrims(); i++)
                if (llAvatarOnLinkSitTarget(i) != NULL_KEY) // llGetNumberOfPrims() > llGetObjectPrimCount(llGetKey()))
                {
                  //  llSetTimerEvent(2);
                  // llOwnerSay("Seated");
                    return;
                }


                { //else 
                   // llSetTimerEvent(0);
                }

        }
    }

    timer()
    {
        integer i;
        for ( i=0; i < llGetListLength(points); i++)
        {
            if (llVecDist(llGetPos(), llList2Vector(points,i))< 7)
            {
               // llOwnerSay("PT = "+i);
                if (i != nextStation)
                {
                    string s = llList2String(messages, i);
                    if (s != "")
                    {
                        llWhisper(0 , "/me <<" +s+ ">>");
                        llTriggerSound("dingdong", 1.0);
                        llWhisper(report_channel, "1>"+s);
                    }
                    nextStation = i;
                    return;
                }
            }
        }

    }    
}