Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

vehicle multiple unsit script

Icarus DuCasse
Registered User
Join date: 28 Jan 2007
Posts: 27
02-27-2007 14:31
Hi,

the last few hours Ive been pulling my hair out to get to a decent llDialog unsit option.
This is what I have atm: a script that puts an avatarsname in a list which is displayed by a llDialog box. All goes well as long as it is only one person sitting in the car. I have other llSittarget scripts in the remaining seat sending a link message to the root when someone sits on it (but this doesn't work) the root converts the received key into a name and puts it in the list. But here it all goes wrong.

Snippet in the main root
CODE

if(change & CHANGED_LINK)
{
key agent =llAvatarOnSitTarget();
if (agent)
{

name1=llKey2Name(agent);
names+=name1;
menu+=names;
key1=agent;
....
}
else
{
names=[];
}



script in one of the seats:

CODE

default
{
state_entry()
{
llSitTarget(<-.38, -.02, 2>, <0,0,-1.0,1>);
}

changed(integer change)
{


if(change & CHANGED_LINK)
{
key id =llAvatarOnSitTarget();
llOwnerSay((string)llKey2Name(id));



if (id)
{
llOwnerSay((string)llKey2Name(id));
//llUnSit(id);

llMessageLinked(LINK_ROOT,0, "name2", id);
}
}
}
}


Any ideas or suggestions where I can enlighten myself?
thanks very much
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
02-28-2007 00:25
You dont show the linked_message handler in the main script? Does it ever fire?
Icarus DuCasse
Registered User
Join date: 28 Jan 2007
Posts: 27
02-28-2007 07:13
Hi Newgate,

The grid is offline atm but Ill try to reconstruct the snippet:

CODE

link_message (...)
{
if(message=="name2")
{
name2+=(string)llKey2Name(id); //putting the seated avatars name
names+=name2; // pushing the name in the names list which will be called by a llDialog
menu+=name2; // pushing it in the menu list, so it can be found by the listen function


Im also not sure how to delete the name again when the avatar unsits. I tried equally as I used the '+' for adding the '-' to substract. but it gives a mismatch error.
for example:
CODE

names -=name2; //gives a mismatch


I realize at this very moment, name2 is a string of the avatars name and its not find because of that.

CODE

names -=(string)name2; //gives a mismatch // this might do the trick


I was thinking about using a sensor, but it seems not necessary. It should be enough to have a change link in every sit script, identify the avatars key, send a message to the main script, convert it to a name and putting it in a list. So when on touch you have the dialog calling the list with names of the avatars? Im grabbing in thin air here.

Thx for taking a look at it
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
02-28-2007 14:28
From: Icarus DuCasse
Hi Newgate,

The grid is offline atm but Ill try to reconstruct the snippet:

CODE

link_message (...)
{
if(message=="name2")
{
name2+=(string)llKey2Name(id); //putting the seated avatars name
names+=name2; // pushing the name in the names list which will be called by a llDialog
menu+=name2; // pushing it in the menu list, so it can be found by the listen function


Im also not sure how to delete the name again when the avatar unsits. I tried equally as I used the '+' for adding the '-' to substract. but it gives a mismatch error.
for example:
CODE

names -=name2; //gives a mismatch


I realize at this very moment, name2 is a string of the avatars name and its not find because of that.

CODE

names -=(string)name2; //gives a mismatch // this might do the trick


I was thinking about using a sensor, but it seems not necessary. It should be enough to have a change link in every sit script, identify the avatars key, send a message to the main script, convert it to a name and putting it in a list. So when on touch you have the dialog calling the list with names of the avatars? Im grabbing in thin air here.

Thx for taking a look at it


Ok, first thing is lists cannot be manipulated that way. You will need to find the index of the name in the list and then delete the entry.

Code Fragment
CODE

integer index = llListFindList( names , name2 );
if(index >= 0)
{
// Name is in the list
names = llDeleteSubList(names , index , index );
}
else
{
// not in list so add ?
}


Secondly, you store two copies of the name, one in menu and one in names?
You dont appear to store the key at all?

You would be better off storing the av's name and the prim number they are say on, then to unseat just send that prim an unseat this person link message.
Icarus DuCasse
Registered User
Join date: 28 Jan 2007
Posts: 27
02-28-2007 15:26
hey Newgate,

thanks for taking time to analyse. Really appreciated.

The problem which I found to arise was that if one got seated all scripts even if they're not in the root call the changed event so all scripts send their message again to the root. In consequence the list soon got overpopulated.

CODE

changed(integer change)
{


if(change & CHANGED_LINK)
{
key id =llAvatarOnSitTarget();
llOwnerSay((string)llKey2Name(id));



if (id)
{
llOwnerSay((string)llKey2Name(id));
//llUnSit(id);

llMessageLinked(LINK_ROOT,0, "name2", id);
}
}


This script in one of the seats call the change event whenever an agent sits in the vehicle disregarding where it sits. Is it possible to do a check in this event whether the agent is seated/unseated on the local prim (prim with script)? I tried some things but failed.
Functions like llDetectedLinkNumber only detect the local prim number and not the one who started the change event? So Im pondering how to distinct change events ... without much result.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
03-01-2007 01:18
From: Icarus DuCasse
hey Newgate,

thanks for taking time to analyse. Really appreciated.

The problem which I found to arise was that if one got seated all scripts even if they're not in the root call the changed event so all scripts send their message again to the root. In consequence the list soon got overpopulated.

This script in one of the seats call the change event whenever an agent sits in the vehicle disregarding where it sits. Is it possible to do a check in this event whether the agent is seated/unseated on the local prim (prim with script)? I tried some things but failed.
Functions like llDetectedLinkNumber only detect the local prim number and not the one who started the change event? So Im pondering how to distinct change events ... without much result.


Any change to the link set will trigger a change event in each script that handles it. But its NOT a problem if you handle the code slightly differently. When ever anyone sits / unsits you just need to rebuild the complete list from scratch. Your seat scripts DONT need any real intelligence apart from to only pass on their current sitter's details if sat on. Then in the main script you store the name, key and the prim it came from.
You could use a strided list but personally I would use three lists, its just a little bit simpler.

When your menu is used you will get back the name, you use this to find its index and then from that look up the prim number. You then send that prim number an UNSEAT message.

Seat Script
CODE

// Seat Script -

// Define constants where possible
integer SEATED = 1000;
integer UPDATEME = 1001;
integer UNSEAT = 9999;

default
{
state_entry()
{
llSitTarget(<-.38, -.02, 2>, <0,0,-1.0,1>);
}

link_message(integer sender_num, integer num, string str, key id)
{
if(UPDATEME == num)
{
// EDIT ----------- BUG FIX
key currentid =llAvatarOnSitTarget();
if(currentid != NULL_KEY)
{
string name = llKey2Name(currentid );
llMessageLinked(LINK_ROOT,SEATED, name, currentid );
}
// END EDIT ----------- BUG FIX
}
else if(UNSEAT == num)
{
// Double check!
key currentid =llAvatarOnSitTarget();
if(currentid == id) llUnSit(id);
}
}
}


Main Script (INCOMPLETE CODE)
CODE

list Names;
list Keys;
list Prims;

// Define constants where possible
integer SEATED = 1000;
integer UPDATEME = 1001;
integer UNSEAT = 9999;


ClearAllLists()
{
Names = [];
Keys = [];
Prims = [];
}

AddName(integer sender_num, string str, key id)
{
Names = (Names = []) + Names + [ str ];
Keys = (Keys = []) + Keys + [ id ];
Prims = (Prims = []) + Prims + [ sender_num ];
}

default
{
state_entry()
{
llSitTarget(<-.38, -.02, 2>, <0,0,-1.0,1>);
ClearAllLists();
}

changed(integer change)
{
if(change & CHANGED_LINK)
{
ClearAllLists();

key id =llAvatarOnSitTarget();
if (id)
{
string name = llKey2Name(id);
AddName(LINK_ROOT,name,id);
llMessageLinked(LINK_SET,UPDATEME, name, id);
}
}
}

link_message(integer sender_num, integer num, string str, key id)
{
if(SEATED == num)
{
AddName(sender_num, str, id);
Names = (Names = []) + Names + [ str ];
Keys = (Keys = []) + Keys + [ id ];
Prims = (Prims = []) + Prims + [ sender_num ];
}
}

listen( integer channel, string name, key id, string message )
{
// Clear down the listen
// CancelListen();

integer index = llListFindList( Names , [ message ] );
if(index >= 0)
{
key target = llList2Key( Keys , index );
integer linknumber = llList2Integer( Prims , index);
if(LINK_ROOT == linknumber)
{
key currentid =llAvatarOnSitTarget();
if(currentid == target) llUnSit(target);
}
else
{
llMessageLinked(linknumber,UNSEAT, name, target);
}
}
}
}


Obviously I've left out the invoking of the dialog.
The above is untested but I think its ok.

You could simplify the main Script Code code slightly more by having a seat script in the root prim as well and handling it exactly like all the other seats. I'll leave that for you to decide.

HtH
Icarus DuCasse
Registered User
Join date: 28 Jan 2007
Posts: 27
03-01-2007 06:38
It really helped. If I can be of any help at your part, altough I doubt itll be a scripting issue, feel free to ask.

Regards,
Icarus
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
Bug Fix!!!!!
03-01-2007 07:42
Newgy screwed up, onlynoticed when rereading the post
I've modified teh original code but will post it here again for clarification

CODE

if(UPDATEME == num)
{
string name = llKey2Name( id );
llMessageLinked(LINK_ROOT,SEATED, name, currentid );
}


Should be
CODE

if(UPDATEME == num)
{
// EDIT ----------- BUG FIX
key currentid =llAvatarOnSitTarget();
if(currentid != NULL_KEY)
{
string name = llKey2Name(currentid );
llMessageLinked(LINK_ROOT,SEATED, name, currentid );
}
// END EDIT ----------- BUG FIX
}
Icarus DuCasse
Registered User
Join date: 28 Jan 2007
Posts: 27
03-01-2007 11:56
no worries, the data you provided was more then enough to come to a working script.
Nonetheless, you have my admiration.

See you around.