Jump to content

What is the secret to reliable teleporters?


Kayaker Magic
 Share

You are about to reply to a thread that has been inactive for 4577 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

     Some time ago I built teleporters to get from one place to another on my sim. I can set up prims that say “Click here to go to the cove” on then. I used the following technique: I set the teleport transmitter to “Sit on Left-Click”. I set a Sit Target standing in front of the transmitter. When someone sits, I send a message to the receiver, (via llRegionSay) it replies with its location. The transmitter then uses posJump to move to the receiver, llUnSits the avatar there and posJumps back.

     This used to work 99% of the time. Occasionally it would stop in transit deep under water or up in the air off-sim. If I hit one of the movement controls the system would realize its mistake and snap me to the correct location.

     But over time it has become more and more unreliable, until EVERY TIME I use one of these teleporters, I first go someplace strange and have to hit the rotate button to finish the teleport.

     So how do I make my teleporters reliable again? Is there a way to get to the destination directly without pausing in odd places along the way?

     I could use the llSitTarget trick, but that only works <=300 meters so it won't work for “click here to TP to the skybox”. I could query the receiver every so often and switch to the llSetTarget trick when the distance is <300 meters, but then I still need a reliable way to teleport longer distances. Any suggestions?

 

Below is my transmitter code:

 

//Teleport button
integer telchan=-101507;        //channel for teleport communication
string name="Test Two";        //name of receiver I talk to
vector spos;
rotation srot;
string notecard;        //for reading parameters
integer line;            //next line to read from notecard
float delay=0.1;        //tenth of a second delay

posJump(vector target_pos)
{
// An alternative to the warpPos trick without all the overhead.
// Trickery discovered by Uchi Desmoulins and Gonta Maltz.  More exact value provided by Fake Fitzgerald.
    llSetPrimitiveParams([PRIM_POSITION, <1.304382E+19, 1.304382E+19, 0.0>, PRIM_POSITION, target_pos]);
}


default
{
    state_entry()
    {
        llSetText("",<0,0,0>,0);
        llSetSitText("teleport");
        llListen(telchan,"","","");        //listen for location commands
        llSitTarget(<0,-1,-1>,llEuler2Rot(<0,0,90>*DEG_TO_RAD));    //set a sit target to hang at
        notecard=llGetInventoryName(INVENTORY_NOTECARD,0);
        line=0;
        if (notecard!="")
            llGetNotecardLine(notecard,0);
    }
    on_rez(integer param)
    {
        llSetText("",<0,0,0>,0);
        llSetPos(llGetPos()+<0,0,1.25>);        //bounce 1.25 meters off the ground
        notecard=llGetInventoryName(INVENTORY_NOTECARD,0);
        line=0;
        if (notecard!="")
            llGetNotecardLine(notecard,0);
    }    
    dataserver (key id,string str)
    {
        if (str!=EOF)
        {
            list parse=llParseString2List(str,["\"","=",";"],[]);
            string cmd=llToLower(llStringTrim(llList2String(parse,0),STRING_TRIM));
            string param=llStringTrim(llList2String(parse,1),STRING_TRIM);
            if (cmd=="" || llGetSubString(cmd,0,0)=="/")
                cmd+="comment";
            else if (cmd=="name")
                name=param;
            else if (cmd=="delay")
                delay=(float)param;
            else if (cmd=="text")
                llSetText(param,<1,1,1>,1);
            else
                llOwnerSay("Bad parameter file line: "+str);
            line += 1;
            llGetNotecardLine(notecard,line);
        }
    }
    changed(integer change)
    {
        if (change&CHANGED_LINK)
        {
            key av=llAvatarOnSitTarget();
            if (av != NULL_KEY)
            {
                llRegionSay(telchan,"ask|"+name);        //ask the receiver for the location
                llRequestPermissions(av,PERMISSION_TRIGGER_ANIMATION);
                spos=llGetPos();
                srot=llGetRot();
                llSetTimerEvent(5);                        //give it time to respond
            }
            else
            {
                posJump(spos);      //return the prim where it came from
                llSleep(delay);     //sometimes a delay helps
                llSetRot(srot);     //put it back in the orientation it was in before
            }
        }
        if (change&&CHANGED_INVENTORY)
        {
            notecard=llGetInventoryName(INVENTORY_NOTECARD,0);
            line=0;
            if (notecard!="")
                llGetNotecardLine(notecard,0);
        }

    }
    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            llStopAnimation("sit");
            llSleep(0.1);
            llStartAnimation("stand_3");
        }
    }

    listen( integer channel, string lname, key id, string message )
    {
        list parse=llParseString2List(message,["|"],[]);
        string cmd=llList2String(parse,0);
        string receiver=llList2String(parse,1);
        key av=llAvatarOnSitTarget();
        if (cmd=="loc" && receiver==name && av!=NULL_KEY)
        {
            llPlaySound("transporter",1);
            llSetTimerEvent(0);         //turn off the watchdog timer
            spos=llGetPos();
            srot=llGetRot();
            vector tpos=(vector)llList2String(parse,2);
            rotation trot=(rotation)llList2String(parse,3);
            llSetRot(trot);
            posJump(tpos+(<0,1,0>-<0,.5,0>)*trot); //+<0,.6,0>*srot);
            llUnSit(av);
        }
    }
    timer()
    {
        llSetTimerEvent(0);
        key av=llAvatarOnSitTarget();
        if (av!=NULL_KEY)
        {
            llSetTimerEvent(0);                        //give up on a responce
            llUnSit(av);
            llWhisper(0,"Teleport failed, try again later");
        }
        
    }
}

 

 

Link to comment
Share on other sites

in addition to what I said in that other thread, try making your mobile portion (the one with that script in it) phantom, make sure that the av is positioned well above the reception surface on landing.... I use 1.5m (via the sit target) + 0.75 of av Height (via agent size), and still en up comming through the floor or bouncing on the ground occasionally (but almost never flying).

if you are going to use permissions to properly stop the sit animation, then do that before you call your region say (which you can move to the permissions event), so that you don't have the possibility of dead code if the listen event queues in front of the permissions event.

the long delays inbetween usually aren't code issues, but rather region issues.... they happen more frequently when the region is very busy...

 

here's the quick code I use, that has nearly the same behavior logic.... in a single prim with the bottom sliced off so that it's center rests on the surface it's targeted to.... I set them up as quickie jobs that I can shift drag and move around at will.

vector gPosLcl;default{    state_entry(){        llListen( -8, llGetObjectName(), "", "" ); //-- listen for same name        llSitTarget( <0.0, 0.0, 1.5>, ZERO_ROTATION ); //-- 1.5m above ground level for this design    }        changed( integer vBitChg ){        if (CHANGED_LINK & vBitChg){            if (~-llGetNumberOfPrims()){ //-- do we have more than one link in the set?                llRegionSay( -8, "Localize" ); //-- yell for our sister to tell us where to go            }else{ //-- package delivered, lets go home.                llSetLinkPrimitiveParamsFast( !!llGetLinkNumber(), //-- should actually be 0                                              [PRIM_POSITION, <1.304382E+19, 1.304382E+19, 0.0>,                                               PRIM_POSITION, gPosLcl] );            }        }    }        listen( integer vIntNul, string vStrNul, key vKeySpk, string vStrMsg ){        if (llGetOwnerKey( vKeySpk ) == llGetOwner()){ //-- double check to make sure we share the same owner            if ("Localize" == vStrMsg){ //-- the other teleporter wants to know where we are, tell them                llRegionSay( -8, (string)llGetPos() );            }else if (ZERO_VECTOR != (vector)vStrMsg && vIntNul = llGetLinkNumber()){ //-- they told us, go there                gPosLcl = llGetPos(); //-- grab current location for the return trip                vector vSizTmp = llGetAgentSize( vKeySpk = llGetLinkKey( 2 ) ); //-- grab av size so we can hack the height                llSetLinkPrimitiveParamsFast( !!vIntNul,                                              [PRIM_POSITION, <1.304382E+19, 1.304382E+19, 0.0>,                                               PRIM_POSITION, (vector)vStrMsg + <0.0, 0.0, vSizTmp.z * 0.75> ] );                llUnSit( vKeySpk ); //-- really should have a slight pause to negate physics after effects, but I was lazy            }        }    }}

 

Link to comment
Share on other sites

  • 5 months later...

You can avoid the funky viewer behavior by having your transporter fly there at less-than-warp speeds.

Still can be pretty fast,   but the scenery is better.   Better for sim crossing too, though we assume your transporters do not need to do that.   (Mine do).

Perhaps it would be enough to slow down to impulse power (i.e. normal use of setpos) a bit just before landing.

 

Link to comment
Share on other sites

little bit o lag there on the reply eh? =D

actually I found the only problem with mine was using the llSLPPFast, instead of just LLSLPP... apparently that .2 second delay gives the region physics enough time to properly register the avatars position (or perhaps just the fact that it's actually sitting)....after changing that it was spot on except when the whole region was lagged

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4577 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...