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;
}
}
}
}
}