Smooth motion, cool script from osgrid

Creating scripts
User avatar
Sherrie Melody
Posts: 273
Joined: Fri Mar 29, 2013 6:56 pm
Has thanked: 201 times
Been thanked: 159 times

Smooth motion, cool script from osgrid

Post by Sherrie Melody »

I have been working on an animated duck :D And as the basis for that, I found a really nice script on osgrid forums. The creator specified that it's free to use, no restrictions. Thought I'd share it here, in case others might enjoy it. The script moves an object smoothly along a path defined in a "config" notecard which defines a series of positions and rotations for the object to go through. You can also configure it to pause or to chat text.

I made a path maker so I could easily generate the lines for positions/rotations. You can find them here: http://www.kitely.com/forums/viewtopic.php?f=26&t=641

With this original script, the object moves from position to position, gradually rotating to the rotation defined for a position as it approaches the position. Okay, I know that reads funny. Anyway, here's the script. You can find it originally posted here: http://forums.osgrid.org/viewtopic.php? ... 7&start=10

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

These users thanked the author Sherrie Melody for the post (total 2):
Constance PeregrineMin Tigerpaw
User avatar
Sarge Misfit
Posts: 254
Joined: Thu Mar 14, 2013 4:10 pm
Has thanked: 5 times
Been thanked: 223 times

Re: Smooth motion, cool script from osgrid

Post by Sarge Misfit »

I have been looking for something like this. :) It should work great in sentry bots, etc :-)
These users thanked the author Sarge Misfit for the post:
Constance Peregrine
Living life on the wrong side of a one-track mind.

National Security Threat Level: Gnat

My site: Excelsior Station
My Kitely World: Misfit's Folly
User avatar
Sarge Misfit
Posts: 254
Joined: Thu Mar 14, 2013 4:10 pm
Has thanked: 5 times
Been thanked: 223 times

Re: Smooth motion, cool script from osgrid

Post by Sarge Misfit »

Well, I gave this script and the pathmaker scripts a shot and ...

They worked great!!

I now have a dozen droids patrolling the Elkay City streets at Regio Excelsior (this is a new level at about 100m above the main landing area).

The only problem I ran into was to change the name of the notecard that your pathmaker generates from paths to config.

42 thumbs up for providing these scripts, Sherrie :D
These users thanked the author Sarge Misfit for the post:
Constance Peregrine
Living life on the wrong side of a one-track mind.

National Security Threat Level: Gnat

My site: Excelsior Station
My Kitely World: Misfit's Folly
User avatar
Sarge Misfit
Posts: 254
Joined: Thu Mar 14, 2013 4:10 pm
Has thanked: 5 times
Been thanked: 223 times

Re: Smooth motion, cool script from osgrid

Post by Sarge Misfit »

It looks like the script shuts down when the world goes offline. I'm thinking, add an on rez state to reset the script. I'm just not scripter enough to do it myself
Living life on the wrong side of a one-track mind.

National Security Threat Level: Gnat

My site: Excelsior Station
My Kitely World: Misfit's Folly
User avatar
Sherrie Melody
Posts: 273
Joined: Fri Mar 29, 2013 6:56 pm
Has thanked: 201 times
Been thanked: 159 times

Re: Smooth motion, cool script from osgrid

Post by Sherrie Melody »

Sarge Misfit wrote:It looks like the script shuts down when the world goes offline. I'm thinking, add an on rez state to reset the script. I'm just not scripter enough to do it myself
:shock: Doh! I forgot about that. In my revised version I added a changed event to the drive state that determines whether the region restarted, but I also did a couple other things that wouldn't fit in the original script.

I'll post an updated version of this original script. Shouldn't take too long. Oh, on the idea of adding an on rez state/reset script, I don't think that would work because the on rez event is only triggered when you actually rez it from inventory of some sort.
User avatar
Sherrie Melody
Posts: 273
Joined: Fri Mar 29, 2013 6:56 pm
Has thanked: 201 times
Been thanked: 159 times

Re: Smooth motion, cool script from osgrid

Post by Sherrie Melody »

Sarge Misfit wrote:
I now have a dozen droids patrolling the Elkay City streets at Regio Excelsior (this is a new level at about 100m above the main landing area).
Wait. before I go updating the script, as originally written, the script was used in a touring object that displays hover text "Sit down and touch me". The object would then follow the configured path once touched.

If you are using it for droids (like robots, right?), you probably want them to wander along a path automatically, once you've configured their notecards. If I have that right, I can update the script to serve that purpose, rather than the touring focus.
User avatar
Sarge Misfit
Posts: 254
Joined: Thu Mar 14, 2013 4:10 pm
Has thanked: 5 times
Been thanked: 223 times

Re: Smooth motion, cool script from osgrid

Post by Sarge Misfit »

Sherrie Melody wrote:
Sarge Misfit wrote:
I now have a dozen droids patrolling the Elkay City streets at Regio Excelsior (this is a new level at about 100m above the main landing area).
Wait. before I go updating the script, as originally written, the script was used in a touring object that displays hover text "Sit down and touch me". The object would then follow the configured path once touched.

If you are using it for droids (like robots, right?), you probably want them to wander along a path automatically, once you've configured their notecards. If I have that right, I can update the script to serve that purpose, rather than the touring focus.
That's exactly what I did, Sherrie.

Set out waypoint/path markers
Run the record adn save
Create the paths notecard
Changed name of notecard to config
Added notecard and script to droids
Touched each droid in turn, two minutes apart

Worked great, loaded them to Kitely
Had to reset them thinking it had to do with the save oar & upload process

Droids working great, floating along everything fine
Went offline

Returned today and all the droids were stopped in their tracks. No hover text, just stopped/suspended.

If I reset the scripts, each droid will return to the off state with the hovertext of "sit and touch". Upon touching, the droid will float over to the starting point (passing through all obstacles) and will resume following it path.

So, my thought would be to use an on rez setup to do the same thing as when you touch to start.
Living life on the wrong side of a one-track mind.

National Security Threat Level: Gnat

My site: Excelsior Station
My Kitely World: Misfit's Folly
User avatar
Sherrie Melody
Posts: 273
Joined: Fri Mar 29, 2013 6:56 pm
Has thanked: 201 times
Been thanked: 159 times

Re: Smooth motion, cool script from osgrid

Post by Sherrie Melody »

Sarge Misfit wrote: That's exactly what I did, Sherrie.



So, my thought would be to use an on rez setup to do the same thing as when you touch to start.
The only thing is (if I am understanding what you mean and I'm not being dense and missing something), an on rez event in the default state won't be triggered when the region restarts, and the script will be in the drive state. The changed event is the only way that I know of to detect a region restart. I modified the script below to include a changed event in the drive state. When it detects a region restart, it finds its home position (first in the notecard), goes there, and starts it path automatically. You still touch to start when you first rez your object to get it going.

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
    osWarpPos (key id, vector destpos ) {
         vector primPos = llList2Vector(osGetPrimitiveParams(id, [PRIM_POSITION]), 0);
         integer jumps = (integer)(llVecDist(destpos, primPos) / 0.3) + 1;
         // Try and avoid stack/heap collisions
         if (jumps > 411)
             jumps = 411;
         list rules = [ PRIM_POSITION, destpos ];  //The start for the rules list
         integer count = 1;
         while ( ( count = count << 1 ) < jumps)
             rules = [] + rules + rules;   //should tighten memory use.
         osSetPrimitiveParams(id, rules + llList2List( rules, (count - jumps) << 1, count) );
         vector primPos2 = llList2Vector(osGetPrimitiveParams(id, [PRIM_POSITION]), 0);
         if ( llVecDist( primPos2, destpos ) > .001 ) //Failsafe
             while ( --jumps ) 
                osSetPrimitiveParams(id, [PRIM_POSITION, destpos]);
    }


    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
    integer     continuous=0;    //loop back through path

    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
    {
       on_rez (integer start_param) {
            llResetScript();
        }

       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(continuous == 1) {
            state drive;
                
            }
       }
       touch_start(integer total_number)
        {
            continuous = 1;
            list homeList = llParseString2List(osGetNotecardLine("config", 0), "=", "");
            vector homePos = llList2Vector(homeList,1);
            osWarpPos(llGetKey(), homePos);
            llSleep(2.0);

            state drive;
       }
    }
    state drive
    {
       state_entry()
       {
          llSetText("", <1,1,1>, 1.0);
          Count = 0;
          SFrame();
        }
        changed (integer change) {
            if (change & CHANGED_REGION_START) { 
                list homeList = llParseString2List(osGetNotecardLine("config", 0), "=", "");
                vector homePos = llList2Vector(homeList,1);
                osWarpPos(llGetKey(), homePos);
                state default;
            }
    
        }

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



Will that work for you?
User avatar
Sarge Misfit
Posts: 254
Joined: Thu Mar 14, 2013 4:10 pm
Has thanked: 5 times
Been thanked: 223 times

Re: Smooth motion, cool script from osgrid

Post by Sarge Misfit »

From your description, it will. Though, won't ALL the droids move to the start at once? No problem since I have a new droid that is larger and suitable as a "solo act" (and maybe cut any lag). Anyway, I'm going to test this shortly and will post the results
Living life on the wrong side of a one-track mind.

National Security Threat Level: Gnat

My site: Excelsior Station
My Kitely World: Misfit's Folly
User avatar
Sherrie Melody
Posts: 273
Joined: Fri Mar 29, 2013 6:56 pm
Has thanked: 201 times
Been thanked: 159 times

Re: Smooth motion, cool script from osgrid

Post by Sherrie Melody »

Sarge Misfit wrote:From your description, it will. Though, won't ALL the droids move to the start at once? No problem since I have a new droid that is larger and suitable as a "solo act" (and maybe cut any lag). Anyway, I'm going to test this shortly and will post the results
Ohh, all your droids have the same path card, don't they. I should take the time to figure out how to save the last "Count" so that the object can just pick up where it left off. I'll try.
Post Reply