This could be a good train script, but..
Posted: Fri Jul 25, 2014 4:29 am
.. I'm new at fully understanding scripts. I tried this one: http://forums.osgrid.org/viewtopic.php?f=5&t=4577 - and it's smooth, and close to what I was looking for, however it's meant for a critter, not a train (it glides up and down on its own). Someone else expanded on the script, setting it up like a tour, using waypoints -- meant for something like a train. Here's my dilemma: This is what I am looking for, however, I can't understand one part of the script. It apparently reads waypoints off a notecard, but the author doesn't give an example. I've used a few other scripts that call on notecards and I understand them, but this has got me confused. In addition, the script itself doesn't activate on touch, even though I saw a touch_start instruction in the code. Any coders around - that are above my super novice level that could help?
Thank you - here's the script):

Code: Select all
// Tour script by Rebekka Revnik
// it's free for everyone, no restrictions
// you may delete my name and claim it as your own script
// but if you give credit it would be nice :-)
// the first part is not mine, thanks and credits goes to Kayaker :-)
// Single Framed (SF) motion without llKeyframedMotion
// original script : Kayaker Magic
// from: http://forums.osgrid.org/viewtopic.php?f=5&t=4577
// minor changes by me
vector SF_spos; //start position
rotation SF_srot; //starting rotation
float SF_stime; //starting time
vector SF_epos; //ending position
rotation SF_erot; //ending rotation
float SF_seconds; //time to move that distance
integer SF_target=-1; //handle of last target position
SFrame()
{
SF_spos=llGetPos();
SF_srot=llGetRot();
SF_stime=llGetTime();
SF_epos = llList2Vector(Points, Count);
SF_erot = llList2Rot(Rots, Count);
SF_seconds=llVecDist(SF_epos, llGetPos()) / TIME;
rotation t=<SF_srot.x-SF_erot.x,SF_srot.y-SF_erot.y,SF_srot.z-SF_erot.z,SF_srot.s-SF_erot.s>;
if ((t.x*t.x + t.y*t.y + t.z*t.z + t.s*t.x)>0.5) SF_erot = <-SF_erot.x,-SF_erot.y,-SF_erot.z,-SF_erot.s>;
llTargetRemove(SF_target);
SF_target=llTarget(SF_epos, 0.1);
}
integer SFnotat()
{
if (SF_target== -1) return TRUE;
float time=llGetTime();
time = (time-SF_stime)/SF_seconds;
if (time>1.0)
{
llTargetRemove(SF_target);
SF_target=-1;
llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,SF_epos,PRIM_ROTATION,SF_erot]);
return TRUE;
}
float emit= 1.0-time;
vector pos=SF_epos*time+SF_spos*emit;
rotation rot = <
SF_erot.x*time+SF_srot.x*emit,
SF_erot.y*time+SF_srot.y*emit,
SF_erot.z*time+SF_srot.z*emit,
SF_erot.s*time+SF_srot.s*emit
>;
emit = llSqrt(rot.x*rot.x+rot.y*rot.y+rot.z*rot.z+rot.s*rot.s);
rot = <rot.x/emit,rot.y/emit,rot.z/emit,rot.s/emit>;
//vector v = llRot2Euler(rot);
vector v = <0.0, 0.0, 1.0> * rot;
//v.x = 0;
//v.y = 0;
//rot = llEuler2Rot(v);
//llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,pos,PRIM_ROTATION,llEuler2Rot(v)]);
llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,pos,PRIM_ROTATION,rot]);
return FALSE;
}
// ab hier hab ich das geschrieben :-)
// Mach dir eine Notecard mit den folgenden Einträgen
// Gross/Kleinschreibung ist nicht wichtig, also DRIVE ist genauso gut wie drive oder Drive
// DRIVE = Position = Rotation die Wegpunkte eben, mit Position und Rotation
// nach dem Wegpunkt (muss aber nicht sein)
// PAUSE = Sekunden hält das Objekt ne Weile an
// TEXT = text sagt den Text im Chat
// now that's my part :-)
// Make a notecard with the folling entries
// it's not case sensitive, for example drive is accepted as DRIVE or Drive
// DRIVE = Position = Rotation the waypoints with given params
// after the waypoint (optionally but but not required)
// PAUSE = seconds makes the object to stay for a while
// TEXT = text says the text in chat
// wie es oben steht, die Schlüsselwörter
// as above, the keywords
string DRIVE = "drive";
string PAUSE = "pause";
string TEXT = "text";
// Name der Notecard
// name of the notecard
string NCNAME = "config";
// Trennzeichen für die Schlüsselwörter
// separator for keywords
string SEPARATOR = "=";
// wie schnell sich das Objekt bewegt
// 1 ist ungefähr 1 Meter pro Sekunde
// Grösser = schneller, aber auch mehr ruckeln
// how fast your object will move
// 1 means appr. 1 m per second
// a greater number ist faster but less smoothly
float TIME = 1.0;
// Stell es auf TRUE, dann kommen Infos im Chat über die Wegpunkte
// set it to TRUE to get informations about the waypoints in chat
integer DEBUG = FALSE;
// Wähle die Sprache, ich kann nur die beiden unten sprechen
// 0 = deutsch, 1 = englisch
// choose language, I speak only the two below
// 0 for german, 1 for english
integer LANGUAGE = 0;
list Points;
list Rots;
list Pause;
list Text;
integer NCLine;
key NCid;
integer Count;
// liest ein Zeile aus der Notecard und speichert sie
// reads a notecard line and saves it
Read(string data)
{
list l = llParseString2List(data, [SEPARATOR], []);
string s1 = llToLower(llStringTrim(llList2String(l, 0), STRING_TRIM));
vector v1 = (vector)llToLower(llStringTrim(llList2String(l, 1), STRING_TRIM));
rotation r1 = (rotation)llToLower(llStringTrim(llList2String(l, 2), STRING_TRIM));
integer x;
if(s1 == DRIVE)
{
if(v1 != ZERO_VECTOR)
{
Points += [v1];
Rots += [r1];
Pause += [0];
Text += [""];
}
} else if(s1 == PAUSE)
{
x = llGetListLength(Pause) - 1;
Pause = llListReplaceList(Pause, [(float)llToLower(llStringTrim(llList2String(l, 1), STRING_TRIM))], x, x);
} else if(s1 == TEXT)
{
x = llSubStringIndex(data, SEPARATOR);
data = llDeleteSubString(data, 0, x);
x = llGetListLength(Text) - 1;
Text = llListReplaceList(Text, [llStringTrim(data, STRING_TRIM)], x, x);
}
}
// Sagt was in der Notecard steht (TEXT = text), ohne den Objektnamen
// es muss aber ein Leerzeichen drin sein und mindestens zwei Wörter haben
// sonst kommt nur der normale Chat mit dem Objektnamen
// says what you wrote in the notecard (TEXT = text) without the object name
// it has to be a space in it and at least two words
// otherwise you'll get only the normal chat with the object name
Say(string s)
{
string s1 = llGetObjectName();
integer x = llSubStringIndex(s, " ");
if(x != -1)
{
string s2 = llGetSubString(s, 0, x - 1);
s = llDeleteSubString(s, 0, x -1);
s = "/me" + s;
llSetObjectName(s2);
}
llSay(0, s);
llSetObjectName(s1);
}
default
{
state_entry()
{
llSetText("", <1,1,1>, 1.0);
Points = [];
Rots = [];
Pause = [];
Text = [];
if(llGetInventoryType(NCNAME) == INVENTORY_NONE)
{
if(LANGUAGE == 0) llOwnerSay("Keine config-NC gefunden.");
else if(LANGUAGE == 1) llOwnerSay("No config nc found.");
} else
{
if(LANGUAGE == 0) llOwnerSay("Lese config, bitte warten...");
else if(LANGUAGE == 1) llOwnerSay("Reading config nc, please wait...");
NCLine = 0;
NCid = llGetNotecardLine(NCNAME, NCLine++);
}
}
dataserver(key requested, string data)
{
if(requested == NCid)
{
if(data != EOF)
{
Read(data);
NCid = llGetNotecardLine(NCNAME, NCLine++);
} else
{
if(LANGUAGE == 0) llOwnerSay("Fertig.");
else if(LANGUAGE == 1) llOwnerSay("Ready.");
if(llGetListLength(Points) == 0)
{
if(LANGUAGE == 0) llOwnerSay("Keine Wegpunkte gefunden.");
else if(LANGUAGE == 1) llOwnerSay("No waypoints found.");
}
else
{
if(LANGUAGE == 0) llOwnerSay((string)llGetListLength(Points) + " Wegpunkte gelesen.");
else if(LANGUAGE == 1) llOwnerSay((string)llGetListLength(Points) + " waypoints read.");
state running;
}
}
}
}
}
state running
{
state_entry()
{
if(LANGUAGE == 0) llSetText("Sitze und berühre mich", <1,1,1>, 1.0);
else if(LANGUAGE == 1) llSetText("Sit down and touch me", <1,1,1>, 1.0);
}
touch_start(integer total_number)
{
state drive;
}
}
state drive
{
state_entry()
{
llSetText("", <1,1,1>, 1.0);
Count = 0;
// Ändere den Text hier drunter nach deinen Wünschen. Der kommt nur beim Start der Tour
// Change the text below as you like. It appears only at the start of the tour
Say("Willkommen bei der Tour auf meiner Insel. Sie dauert etwa 20 Minuten. Viel Spass :-)");
SFrame();
}
not_at_target()
{
if(SFnotat())
{
if(DEBUG)
{
if(LANGUAGE == 0) llOwnerSay("Wegpunkt Nr. " + (string)(Count + 1) + " bei " + (string)llList2Vector(Points, Count));
else if(LANGUAGE == 1) llOwnerSay("waypoint no. " + (string)(Count + 1) + " at " + (string)llList2Vector(Points, Count));
}
if(llList2String(Text, Count) != "") Say(llList2String(Text, Count));
if(llList2Float(Pause, Count) > 0) llSleep(llList2Float(Pause, Count));
Count++;
if(Count == llGetListLength(Points)) state running;
SFrame();
}
}
}