Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Dialog Menu Notecard Giver Question

Min Fairweather
Registered User
Join date: 21 Feb 2007
Posts: 202
03-13-2008 08:58
Hiya,

I'm trying to make a menu driven object that either turns phantom temporarily or gives out a notecard depending on which of two options are clicked on the menu.

I'm using Kyrah's dialog menu script from the library but I can't seem to get the notecard function to work. I know I'm missing something somewhere! Can anyone help me out please?



integer menu_handler;
integer menu_channel;
menu(key user,string title,list buttons)//make dialog easy, pick a channel by itself and destroy it after 5 seconds
{
menu_channel = (integer)(llFrand(99999.0) * -1);//yup a different channel at each use
menu_handler = llListen(menu_channel,"","","";);
llDialog(user,title,buttons,menu_channel);
llSetTimerEvent(5.0);
}

default
{
touch_start(integer t)
{
menu(llDetectedKey(0),"I have read and agree to the laws of this land",["I Agree","Give Rules"]);
}
timer() //so the menu timeout and close its listener
{
llSetTimerEvent(0.0);
llListenRemove(menu_handler);
}
listen(integer channel,string name,key id,string message)
{
if (channel == menu_channel) //in case you have others listeners
{
llSetTimerEvent(0.0);
llListenRemove(menu_handler);
if(message == "I Agree";)
{
//do stuff
}
else if(message == "Give Rules";)
{
llGiveInventory(llDetectedKey(0),"Rules";);//put object name in the ""
}
}
}
}
Stephen Zenith
Registered User
Join date: 15 May 2006
Posts: 1,029
03-13-2008 09:15
The llDetected functions only work within certain events, and listen () isn't one of them. Listen passes the key of the person speaking as a parameter, so you don't need the llDetectedKey there anyway.

Change the

llGiveInventory(llDetectedKey(0),"Rules";);

to

llGiveInventory (key, "Rules";);

Not in-world right now, so I can't check :)
_____________________
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
03-13-2008 09:37
From: Stephen Zenith
The llDetected functions only work within certain events, and listen () isn't one of them. Listen passes the key of the person speaking as a parameter, so you don't need the llDetectedKey there anyway.

Change the

llGiveInventory(llDetectedKey(0),"Rules";);

to

llGiveInventory (key, "Rules";);

Not in-world right now, so I can't check :)


Close... try llGiveInventory (id, "Rules";);

Why? You can't use "llDetectedKey" in a listen. You've defined the "speaker's key as "id" so use that.

Note: this assumes you have a notecard in the object's inventory with the name: Rules
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura
Min Fairweather
Registered User
Join date: 21 Feb 2007
Posts: 202
03-13-2008 09:56
Thanks Winter and Stephen. Using id worked and so that bit of the script is all good now. :)

Sadly I'm now suffering from brain melty death after having worked on this all afternoon. I really should recognise my limitations before starting something like this! I'm sure for a scripter it's 5 minutes work *sighs*.

Here's where I've got so far. I'm pretty sure I've got too many touches and timers and it won't even compile. But this is the point where I need to go and have a beer :)




integer menu_handler;
integer menu_channel;
menu(key user,string title,list buttons)//make dialog easy, pick a channel by itself and destroy it after 5 seconds

{
menu_channel = (integer)(llFrand(99999.0) * -1);//yup a different channel at each use
menu_handler = llListen(menu_channel,"","","";);
llDialog(user,title,buttons,menu_channel);
llSetTimerEvent(5.0);
}



default

{

touch_start(integer t)
{
menu(llDetectedKey(0),"I have read and agree to the laws of this land",["I Agree","Give Rules"]);
}

timer() //so the menu timeout and close its listener
{
llSetTimerEvent(0.0);
llListenRemove(menu_handler);
}

listen(integer channel,string name,key id,string message)
{
if (channel == menu_channel) //in case you have others listeners
{


llSetTimerEvent(0.0);
llListenRemove(menu_handler);

if(message == "I Agree";)

{
touch_start( integer vIntTouches )

{
llSetStatus( STATUS_PHANTOM, TRUE ); //-- make door phantom
llSetAlpha( .5, ALL_SIDES ); //-- make door half transparent
llSetTimerEvent( 15.0 ); //-- wait 15sec from last valid touch before closing
}


timer()

{
llSetTimerEvent( .0 ); //-- stops the timer from repeating every 15sec
llSetStatus( STATUS_PHANTOM, FALSE); //-- make door solid
llSetAlpha( 1.0, ALL_SIDES ); //-- make door opaque again
}
}

else if(message == "Give Rules";)

{
llGiveInventory(id,"Rules";);
}


}
}
}
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
03-13-2008 10:37
From: Min Fairweather
Here's where I've got so far. I'm pretty sure I've got too many touches and timers and it won't even compile. But this is the point where I need to go and have a beer :)


Yeah, step away from it for a while.. and yes, too many touches and listens.

You have one state, called "default". each state can only have one of each kind of "event".

I'm not really sure what it is that you're trying to do here, so here's my guess.

Person clicks the prim. They get a choice "notecard" or "I agree". if they agree, the door turns phantom. If they don't agree, they get nothing. If they choose notecard, they get a notecard. Here's an outline for how that should work.. but it's not actually code.

----------

the Touch..
give dialog to toucher.

The listen...
if (message == "I Agree";) "set phantom and start timer"
if (message == notecard) "notecard"

The timer..
set solid again and stop timer.
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura
Min Fairweather
Registered User
Join date: 21 Feb 2007
Posts: 202
03-13-2008 12:30
Thanks Winter, that is exactly the kind of help I needed! *beams*

I now have a working script that does what I want it to do. However, I really want to make sure it's as clean as possible and not creating any lag.

If anyone has any suggestions on tidying this up please let me know.







integer menu_handler;
integer menu_channel;
menu(key user,string title,list buttons)//make dialog easy, pick a channel by itself and destroy it after 5 seconds

{
menu_channel = (integer)(llFrand(99999.0) * -1);//yup a different channel at each use
menu_handler = llListen(menu_channel,"","","";);
llDialog(user,title,buttons,menu_channel);
llSetTimerEvent(5.0);
}


default

{

touch_start(integer t)
{
menu(llDetectedKey(0),"I have read and agree to the laws of this land",["I Agree","Give Rules"]);
}


listen(integer channel,string name,key id,string message)
{
if(message == "I Agree";)

{
llSetStatus( STATUS_PHANTOM, TRUE ); //-- make door phantom
llSetAlpha( .5, ALL_SIDES ); //-- make door half transparent
llSetTimerEvent( 15.0 ); //-- wait 15sec from last valid touch before closing
}


else if(message == "Give Rules";)

{
llGiveInventory(id,"Rules";);
}


}
timer()

{
llSetTimerEvent( .0 ); //-- stops the timer from repeating every 15sec
llSetStatus( STATUS_PHANTOM, FALSE); //-- make door solid
llSetAlpha( 1.0, ALL_SIDES ); //-- make door opaque again

}}
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
03-13-2008 16:59
menu(key user,string title,list buttons)//make dialog easy, pick a channel by itself and destroy it after 5 seconds
{
menu_channel = (integer)(llFrand(99999.0) * -1);//yup a different channel at each use
menu_handler = llListen(menu_channel,"","","";);
llDialog(user,title,buttons,menu_channel);
llSetTimerEvent(5.0);
}


could read like this:


menu(key user,string title,list buttons)
{
llListenRemove(menu_handler);
menu_channel = (integer)(llFrand(99999.0) * -1);
menu_handler = llListen(menu_channel,"",user,"";);
llDialog(user,title,buttons,menu_channel);
}

3 major changes (aside from removing the comments just to make it easier to read)

1. Added "listenRemove". basically, each time a new menu is sent out, it uses a new channel and creates a new listen. By adding "listenremove" we aren't just filling up the sim with unused listens. Scripts can ususally only open about 60 listens before they crash. Your script would eventually have crashed in this way.

2. Listens use a key, not a string, in the third variable. You had a "NULL_STRING" there, not a "NULL_KEY"... That wasn't properly formed.. though it seemed you were "getting away with it". I've made your listen ONLY listen to the person clicking.

3. I took out the Timer call in the menu. Someone could have clicked your door every 4 seconds and kept it from turning solid.. "holding the door open". Your timer doesn't have handling for closing the listen, so since you're leaving that listen open until the next use, (and now it will only listen to the previous toucher).. it's kind of unneeded.

Some people will say you should ALWAYS close your listens.. and the next time someone clicks, your list listen will be closed and then reopened. One open listen isn't really that big of a deal, especially as it will ONLY hear the toucher (and avatars really can't speak on negative channels without help)


Wanna make it a little bit nicer to the sim? try this. Insert the following line as the first command in your listen event:

llListenRemove(menu_handler);

This will close the only open listen if the clicker pushes either of the two buttons on the dialog. If they log off, or teleport away, or press "ignore".. then that listen will still stay open, but as I mentioned before, this really is a relatively negligible problem, since the script will "recycle" that listen the next time it's used.

You might want to add a "No Thanks" button to the dialog. (you can cancel the listen on that button as well.. and then people who decide they DON'T want to enter your space, are tempted to close the listen with a shiny "no thanks" button.

You CAN add a "timeout" structure to the timer, and use that.. but all things considered, a single open listen on "-random" really isn't all that much strain on the sim.
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura