Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

teleport + accesslist

Kaylan Draken
Registered User
Join date: 2 Dec 2006
Posts: 127
09-04-2007 11:01
Can someone help me with a script i partial self made and partial copied from other scripts.

I want to make a teleport script with a list op people that are allowed to use it and the other
people will teleport to another location.

The script i made sometimes works and sometimes not but the people on the accesslist (whitelist) always have to click on it before they teleport. I hope someone knows a better solution for this. ( The teleport works but not always to the correct location)

This Script is Free to use for everybody who wants it and if i solve the problems i will post the fixed script here too.

key nrofnamesoncard;
integer nrofnames;
list names;
list keynameoncard;
vector target1=<18, 16, 443>; //People that are allowed
vector target2=<19, 9, 401>;

vector offset;

default
{
state_entry()
{
nrofnamesoncard = llGetNumberOfNotecardLines("whitelist";);
}

dataserver (key queryid, string data){

if (queryid == nrofnamesoncard)
{

nrofnames = (integer) data;
llOwnerSay("Found "+(string)nrofnames+ " names in whitelist.";);

integer i;
for (i=0;i < nrofnames;i++){
keynameoncard += llGetNotecardLine("whitelist", i);
}
} else
{
integer listlength;
listlength = llGetListLength(keynameoncard);
integer j;
for(j=0;j<listlength;j++) {
if (queryid == (key) llList2String(keynameoncard,j))
{
names += data;
}
}
}

if (llGetListLength(names) == nrofnames)
{
state Teleport;
}
}
}

state Teleport
{
state_entry()
{
offset = (target2- llGetPos()) * (ZERO_ROTATION / llGetRot());
llSetSitText("Teleport";);
llSitTarget(offset, ZERO_ROTATION);
}

changed(integer change)
{ // something changed
if (change & CHANGED_LINK)
{ // and it was a link change
llSleep(0.5); // llUnSit works better with this delay
if (llAvatarOnSitTarget() != NULL_KEY) { // somebody is sitting on me
llUnSit(llAvatarOnSitTarget()); // unsit him


llResetScript() ;
}
}
}

touch_start(integer i)
{
string nametotest = llDetectedName(0);
llSay(0,llDetectedName(0));
integer j;
for (j = 0; j < llGetListLength(names); j++)
{
if (llList2String(names, j) == nametotest)
{
offset = (target1- llGetPos()) * (ZERO_ROTATION / llGetRot());
}
else
{
offset = (target2- llGetPos()) * (ZERO_ROTATION / llGetRot());
}

}

llSetSitText("Teleport";);
llSitTarget(offset, ZERO_ROTATION);
}
}
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
09-04-2007 11:32
First let's consider what happens in the touch_start handler for the Teleport state. It's running through all the elements of "names" looking for a match with the toucher. When it finds a match it sets the teleport offset accordingly--but then it keeps going, so if there's another name on the list, it will change to the undesired offset. Probably just testing the result of a llListFindList would be easier.

And then there's the way that list is created in the dataserver handler of default state. It's easier to just read the lines one at a time until EOF, rather than trying to read them in a loop where the end of the loop is known from the number of lines in the notecard. This might work as written (not sure), but it's wading through the "keynameoncard" list of query IDs for each result the dataserver returns, which is a lot more bookkeeping than just having the one query extant at any time until all the lines have been read in and EOF is seen. (It might take a little longer to do it that way, but it'll use less resources, and will surely be easier to debug and maintain.)
Squirrel Wood
Nuteater. Beware!
Join date: 14 Jun 2006
Posts: 471
09-05-2007 00:28
Instead of comparing every list element in a for loop you should make use of llListFindList. This will work much faster and will return the list element if something is found and otherwise -1.
Kaylan Draken
Registered User
Join date: 2 Dec 2006
Posts: 127
09-05-2007 07:18
Thanks for your answer i will try to do that i am not very good in scripting and to
find out how this is working will take me some time.

Does anyone know how i can teleport without first have to click on it?
U use the click event to detect the name of the person who want to teleport.
and than the person has to right click and select teleport

if it is possible i want to do it with 1 click. (left click or right click and teleport)

i can't use state_entry or the on_rez for that.
Maybe it can be done in the Changed event but i am not certain of that and i
don't know how i can do that.

Thanks
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
09-05-2007 10:19
From: Kaylan Draken
Thanks for your answer i will try to do that i am not very good in scripting and to
find out how this is working will take me some time.

Does anyone know how i can teleport without first have to click on it?
U use the click event to detect the name of the person who want to teleport.
and than the person has to right click and select teleport

if it is possible i want to do it with 1 click. (left click or right click and teleport)

i can't use state_entry or the on_rez for that.
Maybe it can be done in the Changed event but i am not certain of that and i
don't know how i can do that.

Thanks
The script in the original post uses the offset in llSitTarget to move the avatar. But llSitTarget takes effect immediately when somebody sits on the prim, so that won't work if one doesn't know the destination until after the avatar is already seated--and with only one click, that click must be used for making the avatar sit. So, instead of llSitTarget, we have to do something that can vary the destination once the seating has taken place.

The warpPos algorithm can move the prim to the destination while the avatar is seated (upon CHANGED_LINK), so one can use the result of llAvatarOnSitTarget() to dispatch different avatars to different destinations. There are several examples of warpPos based teleporter scripts to browse through in the Scripting Library forum.

In this case, the code currently in the touch_start() handler would belong in changed(), where llAvatarOnSitTarget() is known not to be NULL_KEY; one twist is that llDetectedName() isn't defined in a changed() event--instead, there's llAvatarOnSitTarget(), which is a key (whereas the notecard contains names). Because the agent to be teleported will be in the same sim, it should be fine to convert that with something like:

key seatedAvatarKey = llAvatarOnSitTarget();
if (seatedAvatarKey != NULL_KEY)
{
string nametotest = llKey2Name(seatedAvatarKey);
...