views:

198

answers:

2

I'm trying to make the following script only work when a user in a Certain Group can teleport to the specified x,y,z coordinate.

Source: www.heatonresearch.com

// Scripting Recipes for Second Life
// by Jeff Heaton (Encog Dod in SL)
// ISBN: 160439000X
// Copyright 2007 by Heaton Research, Inc.
//
// This script may be freely copied and modified so long as this header
// remains unmodified.
//
// For more information about this book visit the following web site:
//
// http://www.heatonresearch.com/articles/series/22/

vector target=<190, 197, 64>;

vector offset;

default
{    
    moving_end()
    {
        offset = (target- llGetPos()) * (ZERO_ROTATION / llGetRot());
        llSitTarget(offset, ZERO_ROTATION); 
    }

    state_entry()
    {
        llSetText("Teleport pad",<0,0,0>,1.0);
        offset = (target- llGetPos()) * (ZERO_ROTATION / llGetRot());
        llSetSitText("Teleport");
        llSitTarget(offset, ZERO_ROTATION);      
    }

    changed(integer change) 
    { 
        if (change & CHANGED_LINK) 
        { 
            llSleep(0.5); 
            if (llAvatarOnSitTarget() != NULL_KEY) 
            { 
                llUnSit(llAvatarOnSitTarget()); 
            }
        }
    }

    touch_start(integer i)
    {
        llSay(0, "Please right-click and select Teleport");
    }
}
    The teleport script uses two global variables. They are.

vector target=<190, 197, 64>;
vector offset;    The target is the coordinate that the teleport script should send the user to. The offset is calculated based on the target and the current position of the teleporter. The offset is the distance that must be traveled to reach the target, starting from the teleporter.

    Whenever the teleport pad is moved, the offset must be recalculated. The sit target is then updated.

moving_end()
{
 offset = (target- llGetPos()) * 
  (ZERO_ROTATION / llGetRot());
 llSitTarget(offset, ZERO_ROTATION); 
}    Likewise, when the teleport pad is first created, the offset must be recalculated. Additionally, the sit text is specified. Rotation is also taken into account and neutralized. 

state_entry()
{
 llSetText("Teleport pad",<0,0,0>,1.0);
 offset = (target- llGetPos()) * 
  (ZERO_ROTATION / llGetRot());
 llSetSitText("Teleport");
 llSitTarget(offset, ZERO_ROTATION);      
}    When a user sits on the teleport pad, their avatar sits at the target location. The avatar is then stood up.

changed(integer change) 
{ 
 if (change & CHANGED_LINK) 
     { 
  llSleep(0.5); 
  if (llAvatarOnSitTarget() != NULL_KEY) 
  { 
   llUnSit(llAvatarOnSitTarget()); 
  }
 }
}

Ideas?

+1  A: 

I haven't worked in SecondLife for a while, but isn't sit target maximized to 10 meters distance, anyway? And can't people just as easily use sit targets to get past walls and into areas that they shouldn't be in? The best way to do this is not to use scripts (because they can always be bypassed, even push scripts for area security and the like), and instead to just use SecondLife's built-in land security for your plot. Just don't allow anybody except your group to access that parcel at all.

If you really want to do it your way, the function you're looking for is llSameGroup. Just make sure to assign the proper group to your object, then llSameGroup(key id) will return whether or not the passed id is in the same group as the object.

Because SecondLife sucks in many ways in terms of object access and catching events, if I remember correctly you're going to have to keep the sit target in the wrong place at first, then only move it to the correct location if the user sitting is in the same group. Otherwise, the best you can do is have the user sit on it, and because the target is moved already, by the time your script kicks them off your teleporter they will already have teleported where you don't want them to go.

A better option might be to make a teleporter that doesn't use sit target, but actually moves itself to wherever the target location is. That way, you can make it so that it simply doesn't move unless someone of the same group is sitting in it. Doing that is very very simple.

vector targetPos = <100,100,100>;
vector originPos;

default
{
    state_entry()
    {
        originPos = llGetPos();
    }

    changed(integer type)
    {
        if(type & CHANGED_LINK && llGetAvatarOnSitTarget() != NULL_KEY)
        {
            llSetTimerEvent(0.1);
            llWhisper(0,"Going up!");
        }
    }

    timer()
    {
        key sitter = llAvatarOnSitTarget();

        //If someone is not sitting here, go back home.
        if (sitter == NULL_KEY)
        {
            llSetPos(originPos);

            //If we've reached the origin, stop the timer.
            if (llGetPos() == originPos)
            {
                llSetTimerEvent(0.0);
            }
        }
        //If someone is sitting here, go towards the teleport.
        else
        {
            //Before we move, make sure that they're in our group.
            if (llSameGroup(sitter))
            {
                llSetPos(targetPos);
            }
            else
            {
                llUnsit(sitter);
                llWhisper(0,"Get off me, man!");
            }

            //If we've reached the target, unsit the sitter.
            if (llGetPos() == targetPos)
            {
                llUnsit(sitter);
                llWhisper(0,"We've arrived!");
            }
        }
    }
}

I just wrote that from scratch after having not played SL for more than a couple years, so please let me know everyone if you spot errors. :-)

Eli
A: 

Yeah, there appears to be an error somewhere. I'm pretty sure all brackets are closed so it's most likely in the body of the script. I'll keep looking, let you know if I spot it.