Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Touch-activated Listens

Olmy Seraph
Valued Member
Join date: 1 Nov 2004
Posts: 502
02-01-2005 11:45
This is a tangent to the discussion in /54/f8/34253/1.html but since it's not really part of that topic I'm spawning a new thread.

The approach I take for much of my architectural automation avoids having lots of listens going all the time, but uses touch-based switches around the house. Of course this won't work for attachments, but it's good for land-based builds.

I can't get into SL to grab the code right now, but the way it works is thus:

1) Touch the control object. The touch_start() handler presents an llDialog() to the av presenting a list of command options, and spawns an llListen to receive the result of the dialog. The listen listens to the detected av on a private channel.
2) Av clicks the command option. The dialog sends its command as a message to the detected av on the private channel.
3) Listener gets the command message on private channel. First act is to delete its handler, then it processes the command.

This works really well for all sorts of uses, and keeps listen lag to an absolute minimum. If you have more complex commands that you want the flexibility of parsing a chat message for parameters rather than using a dialog, you can still spawn the listener with a touch and have it remove itself after one use or a short period of time.

UPDATE: I got the code and pared it down to a simple framework. Enjoy.

CODE

integer DialogChannel = 42;
integer ListenHandle = 0;

default {
touch_start(integer total_number) {
ListenHandle = llListen(DialogChannel, "", llDetectedKey(0), "");
llDialog(llDetectedKey(0),
"Option:", ["CommandOne", "CommandTwo"], DialogChannel);
}

listen(integer channel, string name, key id, string message) {
llListenRemove(ListenHandle);

if ( message == "CommandOne" ) {
llSay(0, "Executing Command One...");
// ...
} else if ( message == "CommandTwo" ) {
llSay(0, "Executing Command Two...");
// ...
} else {
return;
}
}
}
_____________________
Some people are like Slinkies... not really good for anything, but they sure bring a smile to your face when you push them down the stairs.
Zuzi Martinez
goth dachshund
Join date: 4 Sep 2004
Posts: 1,860
02-01-2005 12:02
that's a really good idea. i never thought about doing that kind of thing with llDialog. if all the active parts of all the scripts in sl were "on demand" only like that the world would be a better place.
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
02-01-2005 14:25
The only problem there is your commands would likely all need to be done by the same person or organization. My advice would be to generate a complete-newbie-friendly scripted version of this and release it into the wild.

Unfortunately, Zuzi, not every person in SL knows enough about LSL to have even an inkling of what they're doing to sims. If we could solve that problem, SL would be a better place. :p
_____________________
---
Tread Whiplash
Crazy Crafter
Join date: 25 Dec 2004
Posts: 291
Guide...
02-01-2005 16:12
Jeffrey -

I'm putting together an ambitious LSL tutorial & complete guide for people who have never programmed before in their life (all the manuals I've seen so far assume prior programming experience; and ignore the people out there modd'ing free scripts without knowing what they're doing).

I used to run various websites teaching people how to make add-on levels for games like Quake & Half-Life (one of mine was printed in the HL manual, actually)... So I'm confident I can teach people ---

But of course, there's no way I can force users to read it before making things in SL... :rolleyes:

Take care,

--Noel "HB" Wade
(Tread Whiplash)
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
02-01-2005 17:01
My smart hair script closes it's listens, I also use a timer to clean up after the ingnore button.
Adam Marker
new scripter
Join date: 2 Jan 2004
Posts: 104
02-01-2005 18:31
Just curious ... why won't the technique work for attachments? I have had attachments do things when touched. Has that ability changed, or is there some other limitation?
Olmy Seraph
Valued Member
Join date: 1 Nov 2004
Posts: 502
02-01-2005 19:19
From: Adam Marker
Just curious ... why won't the technique work for attachments? I have had attachments do things when touched. Has that ability changed, or is there some other limitation?

I didn't think you could get a pie menu to touch an attachment. Maybe I'm mistaken there.
_____________________
Some people are like Slinkies... not really good for anything, but they sure bring a smile to your face when you push them down the stairs.
Frickin Shark
Registered User
Join date: 23 Dec 2004
Posts: 4
02-01-2005 19:27
From: Olmy Seraph
I didn't think you could get a pie menu to touch an attachment. Maybe I'm mistaken there.



just left-click it..

also add a llListenRemove(ListenHandle); right before your listen call, and probably after your listen event does its IF block
Cross Lament
Loose-brained Vixen
Join date: 20 Mar 2004
Posts: 1,115
02-01-2005 19:58
From: Olmy Seraph
I didn't think you could get a pie menu to touch an attachment. Maybe I'm mistaken there.


I'm pretty sure you can't get the 'Touch' option from an attachment, even if it is scripted to respond to touches. You'll just get the standard "I right clicked on an avatar" sort of menu instead.

Frickin Shark is correct, just left-clicking on the attachment will trigger the touch() event normally. Frickin Shark also has possibly the best name, evar. (puts a laser on his/her head) :)
_____________________
- Making everyone's day just a little more surreal -

Teeple Linden: "OK, where did the tentacled thing go while I was playing with my face?"
Rysidian Rubio
Ruby Red Head
Join date: 14 Jan 2004
Posts: 263
02-01-2005 21:29
Olmy,
Whenever you use a llDialog you should setup a timer which clears the listen, because if the user clicks ignore, or simply doesn't click anything, then the listen will stay activated. Here's your code with a timer added to show what I mean. I also changed your indentation (sorry) but it was confusing to me how you had it.
CODE
integer DialogChannel = 42;
integer ListenHandle = 0;

default
{
touch_start(integer total_number)
{
ListenHandle = llListen(DialogChannel, "", llDetectedKey(0), "");
llSetTimerEvent(30);
llDialog(llDetectedKey(0),"Option:", ["CommandOne", "CommandTwo"], DialogChannel);
}

listen(integer channel, string name, key id, string message)
{
llSetTimerEvent(0);
llListenRemove(ListenHandle);

if ( message == "CommandOne" )
{
llSay(0, "Executing Command One...");
// ...
}
else if ( message == "CommandTwo" )
{
llSay(0, "Executing Command Two...");
// ...
}
else
{
return;
}
}

timer()
{
llSetTimerEvent(0);
llListenRemove(ListenHandle);
}
}
Olmy Seraph
Valued Member
Join date: 1 Nov 2004
Posts: 502
02-01-2005 23:03
From: Rysidian Rubio
Olmy,
Whenever you use a llDialog you should setup a timer which clears the listen, because if the user clicks ignore, or simply doesn't click anything, then the listen will stay activated. Here's your code with a timer added to show what I mean. I also changed your indentation (sorry) but it was confusing to me how you had it.

Thanks Rys. I know, I'm bad about non-standard braces/indenting, cause I prefer tighter formatting that fits more lines on a page. That's a good improvement with the timer, I had forgotten about the ignore case.

I think I'll add this snippet to the wiki examples. It's the sort of thing that is so easy to do and can make a big difference in sim performance.
_____________________
Some people are like Slinkies... not really good for anything, but they sure bring a smile to your face when you push them down the stairs.
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
02-02-2005 04:24
I use this in my trees, except I make the parts listen on a random channel everytime so that I can have multiple "pending" commands. There is a timer to remove the listen after 20 or 30 seconds. If you already use the timer use the llSensorRepeat instead ;)
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
Kyrah Abattoir
cruelty delight
Join date: 4 Jun 2004
Posts: 2,786
02-04-2005 02:13
i would add a random channel picking if you want to add a bit of "security" (players can type commands by hand )

CODE

integer DialogChannel;
integer ListenHandle = 0;

default
{
touch_start(integer total_number)
{

//picking a random channel each time
DialogChannel = (integer)llFrand(999999.0);

ListenHandle = llListen(DialogChannel, "", llDetectedKey(0), "");
llDialog(llDetectedKey(0),
"Option:", ["CommandOne", "CommandTwo"], DialogChannel);
}
listen(integer channel, string name, key id, string message)
{
llListenRemove(ListenHandle);
if ( message == "CommandOne" )
llSay(0, "Executing Command One...");

else if ( message == "CommandTwo" )
llSay(0, "Executing Command Two...");
else
return;
}
}
_____________________

tired of XStreetSL? try those!
apez http://tinyurl.com/yfm9d5b
metalife http://tinyurl.com/yzm3yvw
metaverse exchange http://tinyurl.com/yzh7j4a
slapt http://tinyurl.com/yfqah9u
Frickin Shark
Registered User
Join date: 23 Dec 2004
Posts: 4
02-06-2005 00:31
From: Kyrah Abattoir
i would add a random channel picking if you want to add a bit of "security" (players can type commands by hand )

uhh

CODE
DialogChannel = (integer)(llFrand(20000) - 40000);


wouldnt that be slightly more secure?

Also, that way you wont risk it accidentally llFrand-ing to 0.9999, and setting teh channel to 0
Rhombur Volos
King of Scripture & Kebab
Join date: 6 Oct 2004
Posts: 102
02-06-2005 12:24
From: Frickin Shark
uhh

CODE
DialogChannel = (integer)(llFrand(20000) - 40000);


wouldnt that be slightly more secure?

Also, that way you wont risk it accidentally llFrand-ing to 0.9999, and setting teh channel to 0


Heh, yes. With that code, you'll get a random number between -20000 and -40000 :P
Tread Whiplash
Crazy Crafter
Join date: 25 Dec 2004
Posts: 291
Negative?
02-06-2005 12:36
Frickin -

I believe the code you posted will end up producing a negative number. :rolleyes:

I usually do something similar, but in my own wierd way of course:

CODE

//Get a random channel between 40,000 and 49,000, in increments of 1000
integer myListenChannel = llRound(llFrand(9) + 40) * 1000;


I go in even multiples of 1,000 so that I can pass this channel on to rezzed objects in the on_rez() "start_param" plus I can pass a value between 0 and 999 as well. In effect, I'm passing two values at the same time:
CODE

//On the main object:
rez_start_param = g_someSmallValue + myListenChannel;
llRezObject("Some Object", somePosition, ZERO_VECTOR, someRotation, rez_start_param);
.
.
.
.
//In the rezzed object:
on_rez(integer start_param)
{
if(start_param != 0)
{
g_specialNumber = (start_param % 1000);

g_listenChannel = start_param - g_specialNumber;
}
}


If that sort of "feature" isn't useful in your situation, you could easily increase the number of possible channels by altering the power of 10 that you use:

CODE

//Get a random channel between 40,000 and 49,000, in increments of 10
integer myListenChannel = llRound(llFrand(900) + 4000) * 10;


Take care,

--Noel "HB" Wade
(Tread Whiplash)