Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Hud-controlled Scripted Objects

Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
05-25-2008 01:52
Controlling scripted items via a HUD can be something of a pain since there isn't a function that allows the HUD to speak for the wearer. Scripts can be written to listen for commands on a particular channel of course but that causes a problem in itself: if two avs are using the same device in close proximity, one will find his device responding when another activates hers. Custom-built scripts using obscure channels are another option but who wants to make an SL career out of editing the same script over and over and ...

Inelegant get-arounds such as extra dialog menus or (Heaven's to Betsy!) spoken commands in chat seem to be the most popular options - but we all know where that leads so let's just quietly move along ...

Users of ZHAO II animation overriders may very well find this solution by Johan Laurasia useful. The first piece is dropped into the HUD itself.

CODE


// Object or Hud says its name on an obscure channel so that it can be recognised by another object it is seeking to control:

default
{
state_entry()
{
llSay(243,"MyName:" + llGetObjectName());
}
}



Note: Since the HUD needs to distinguish itself from others, users of modifiable AOs should rename the item accordingly (Ethen_AO, for instance). The channel can of course be anything - so long as it isn't open chat, please! It can even be the same channel for the same product worn by another av.

The next piece should be worked into the scripted item itself:

CODE


// Scripted object seeks out and registers the controlling object or Hud's name so that it can follow instructions:

integer handle;
string objectName;
default
{
state_entry()
{
// set up an open listen on channel 243:
llListen (243,"",NULL_KEY,"");
}

listen (integer channel, string name, key id, string message)
{
// look for "MyName:", if not found test = -1:
integer test = llSubStringIndex (message, "MyName:");
if (test != -1)
{
// extract the name of the object...
objectName = llGetSubString (message, test + 1, -1);
// remove the open listen:
llListenRemove (handle);
handle = llListen (243, objectName, NULL_KEY, "message to scripted object here");
}
}

}



I have tested this with two alts wearing the same item and neither HUD interferes with items worn by the other av. Any suggestions or improvements would be welcome.

Thanks again to Johan Laurasia for his patience, time and ingenuity in providing this solution.
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
05-25-2008 03:32
I may be missing something in your example but why doesn't simply using:

llListen (243, "", llGetOwner(), "";);

...solve your cross-talk problem? In this case only the owner will be 'heard' by the listen event handler.

By definition a HUD is always owned by its user.
Day Oh
Registered User
Join date: 3 Feb 2007
Posts: 1,257
05-25-2008 03:42
llGetOwnerKey applies well here, with one drawback: the object must still exist
_____________________
Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
05-25-2008 03:59
From: Pale Spectre
I may be missing something in your example but why doesn't simply using:

llListen (243, "", llGetOwner(), "";);

...solve your cross-talk problem? In this case only the owner will be 'heard' by the listen event handler.

By definition a HUD is always owned by its user.


I tried this but it is a common issue for HUD-controlled objects: basically the HUD cannot speak directly for the owner. The scripted object doesn't get the message.
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
05-25-2008 04:47
Then I don't think I understand the problem you're trying to solve. :o

If you have a HUD attached AO there are three ways to control it.

Typing... in which case it's the owner talking.
llDialog ... in which case it's the owner talking.
Custom linkset HUD ...in which case llMessageLinked is the way to go (no listens required).

Incidently, the later ZHAO AO uses llMessageLinked.

How are you communicating with the AO?
racush Cheeky
Registered User
Join date: 23 Jan 2006
Posts: 23
05-25-2008 06:01
Would applying a filter to this listen event be what is called for in this case I've set up quite a few objects controlled via a hud and never picks up crosstalk between users.

an example would be:

if ((id == llGetOwner()) || (llGetOwner() == llGetOwnerKey(id)))

I hope this helps in some way :)
Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
05-25-2008 06:03
Pale Spectre, I'm using a macro notecard within the AO to activate the attachment. The HUD says the message on a silent channel when I click the appropriate button and the attachment responds to it.

Thanks for the suggestions but I want to avoid the first two cases where the owner is talking because I believe my AO should be able to pass instructions onto attachments my av is wearing *without* the trouble of my having to type a command every time or cluttering the screen with yet another dialog menu and another button to click. If I understand you correctly regarding the custom linkset HUD, the idea of putting another HUD up on my screen when I already have one there to do the job just isn't a solution for similar reasons - more inventory, more screen clutter.

Even if the extra HUD were a viable solution and even if I understand correctly that llMessageLinked is a more efficient solution, I don't see how it will work without having to customise the script everytime I give away a copy of the item (I don't have the time to waste on sales in SL, that's for sure).

Perhaps I'm missing something in your suggestion but if I didn't make these points crystal clear in my original post, it is only because I thought the deficiencies of the alternatives were clear enough already. Whether I'm right or wrong, I guess I should just put it down to experience.

From: racush Cheeky
Would applying a filter to this listen event be what is called for in this case I've set up quite a few objects controlled via a hud and never picks up crosstalk between users.


Thanks for that, Racush. Admittedly I havn't tried the llGetOwnerKey(id) method, which Day Oh also suggested above. I'll try and see if I can get it to work.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
05-25-2008 07:39
I am sorry Ethen but what you are asking about is barebones hud communications. Take your time & learn, it will all come to you in a surprisingly short amount of time but please don't start handing these out to people yet. SL has more then enough inefficient scripts to deal with as it is.

Learn, play, explore and let your scripting skills grow in the process.

Post your code here and we will be more then glad to give you some pointers.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
05-25-2008 08:30
I'm fully aware of the vicissitudes of the learning process, Jesse, and flawed examples can be every bit as instructive as the most finely polished piece of script - especially when a good solution is presented. Thankfully, I have found some very constructive advice on the script in question - both within and without this forum - and I hope others will also learn from it.

But I could well do without that wearily patronising tone, however well-meant the sentiments may be.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
05-25-2008 09:20
if ((id == llGetOwner()) || (llGetOwner() == llGetOwnerKey(id)))

That's exactly what I do in my objects that can be controlled through chat or via HUD button clicks. It's short, sweet, and it works. Multiple owners can be in close proximity, the objects and HUDs all use the same channel (so no editing needed by the end-user), and you never react to someone else's HUD.
Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
05-25-2008 09:48
Thanks again, Day, Racush and (sharp intake of breath) Ziggy. I'm very much the wiser for your advice - and I guess SL will be a little less laggier for it too!
Keiki Lemieux
I make HUDDLES
Join date: 8 Jul 2005
Posts: 1,490
05-25-2008 10:45
From: Ziggy Puff
if ((id == llGetOwner()) || (llGetOwner() == llGetOwnerKey(id)))

That's exactly what I do in my objects that can be controlled through chat or via HUD button clicks. It's short, sweet, and it works. Multiple owners can be in close proximity, the objects and HUDs all use the same channel (so no editing needed by the end-user), and you never react to someone else's HUD.

Yep, Ethen, Ziggy's solution is what I was trying to explain on my blog. The device you are trying to control should listen for commands from the owner and from any object owned by the same owner.
_____________________
imakehuddles.com/wordpress/
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
05-25-2008 11:04
From: racush Cheeky

if ((id == llGetOwner()) || (llGetOwner() == llGetOwnerKey(id)))

In fact one doesn't even need the first clause there, since an avatar is treated as its own owner. So, if (llGetOwnerKey(id) == llGetOwner()) { } will serve perfectly well.

In general I just put the line

if (llGetOwnerKey(id) != llGetOwner()) return;

at the start of control listen events, and have them unfiltered by key.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!

http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal

http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
05-25-2008 11:10
From: Ethen Drechsler
I'm fully aware of the vicissitudes of the learning process, Jesse, and flawed examples can be every bit as instructive as the most finely polished piece of script - especially when a good solution is presented. Thankfully, I have found some very constructive advice on the script in question - both within and without this forum - and I hope others will also learn from it.

But I could well do without that wearily patronising tone, however well-meant the sentiments may be.

Sorry if this has offended your sensibilities, that was not the intent. I have a very long track record here of encouraged people to learn. But I was not responding to:

"flawed examples can be every bit as instructive as the most finely polished piece of script"

I was responding specifically to this statement by you:

"I don't see how it will work without having to customise the script everytime I give away a copy of the item"

Big difference bewteen beta scripts, example scripts and giving scripts to others to use. That was the point. Hopefully we will see much more of you here and we will all continue to learn.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
05-25-2008 11:44
From: racush Cheeky
if ((id == llGetOwner()) || (llGetOwner() == llGetOwnerKey(id)))

You actually don't need both of those conditions because llGetOwnerKey() is idempotent. That is, llGetOwnerKey(llGetOwner())==llGetOwner() always. So you can just use:

CODE

if (llGetOwnerKey(id) == llGetOwner()) { ... }
Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
05-26-2008 00:52
From: Jesse Barnett
Big difference bewteen beta scripts, example scripts and giving scripts to others to use. That was the point.

My sincere apologies, Jesse. I thought you were telling me off for bringing the script to the forum. Point taken, I wouldn't want to distribute an item of any description that doesn't work properly or, worse, that may contribute to lag.

If I understand the general consensus here, would the following be satisfactory? I've included the full script of the attached item for a more comprehensive evaluation. The lengthy particle parameter shenanigans have been replaced by an ellipsis - I don't suppose they're relevant. (The little 'Say' script has been removed from the HUD since it is no longer required.)

CODE


list particle_parameters=[];

float SystemSafeSet = 0.00;

float SystemAge = 1.5;

StartParticles()
{
SystemSafeSet = SystemAge;
llParticleSystem([ ... ]);
llSleep(SystemAge);
SystemSafeSet = 0.00;
}

default
{
changed(integer change)
{
if(change & CHANGED_OWNER)
{
llResetScript();
}
}
state_entry()
{
SystemSafeSet = 0.00;
SystemAge = 1.5;
llListen(243, "", NULL_KEY, "");
}
listen(integer channel, string name, key id, string message)
{
if (llGetOwnerKey(id) != llGetOwner()) return;
{
llListen (243, "", NULL_KEY, "Message goes here");
}
StartParticles();
}
}



This appears to work when tested in the company of a few alts wearing similar items, although I haven't the experience to judge it's effect on lag.

Perhaps my problem is that I failed to make provision for changed owner and resetting the script?
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
05-26-2008 06:18
From: Ethen Drechsler
My sincere apologies, Jesse. I thought you were telling me off for bringing the script to the forum. Point taken, I wouldn't want to distribute an item of any description that doesn't work properly or, worse, that may contribute to lag.

No problem, looking at your script, I take it that you code in other languages? It doesn't look like the normal noob, 3 posts to the forum script :)
The indents are off thou, which is great because it gives me a chance to introduce a really great, freebie, outside script editor that can also run scripts to an extent:

http://www.lsleditor.org/Download.aspx

Was created by Alphons Jano over about a years time. It can make your life much easier.

From: Ethen Drechsler

This appears to work when tested in the company of a few alts wearing similar items, although I haven't the experience to judge it's effect on lag.

Perhaps my problem is that I failed to make provision for changed owner and resetting the script?

Yep, that would have done it. Script looks clean and should be fine.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
05-26-2008 06:42
Thanks for the link to the script editor, Jesse. I'll download that asap.
From: Jesse Barnett
It doesn't look like the normal noob, 3 posts to the forum script :)

As for coding in other languages, I just like to keep things neat, that's all. I have some experience with Javascript but I don't think I will ever write a script from scratch. I tend towards the Victor Frankenstein method of stitching whatever bits I can find together - and like the man himself, I often have occasion to regret the results.

There are bits of scripts by Debbie Trilling and Seagel Neville in this example along with the entrails of a Jopsy Pendragon particle emitter.
Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
One further question ...
05-26-2008 23:16
If I have three items that run variations of the script, which are often but not always activated at the same time, would it be better to use different channels for each or not?

Note: I have been careful to do the '( age / rate ) * count' calculation on the particle emissions and minimise the respective particle counts.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
05-27-2008 11:34
From: someone
Thanks again, Day, Racush and (sharp intake of breath) Ziggy.


Uh oh, sharp intake of breath! I'm not sure if that's a good thing or a bad thing :)

From: someone
llGetOwnerKey(llGetOwner())==llGetOwner() always


Learn something new every day. Thanks for that tip.
Keiki Lemieux
I make HUDDLES
Join date: 8 Jul 2005
Posts: 1,490
05-27-2008 15:52
From: Ethen Drechsler
My sincere apologies, Jesse. I thought you were telling me off for bringing the script to the forum. Point taken, I wouldn't want to distribute an item of any description that doesn't work properly or, worse, that may contribute to lag.

If I understand the general consensus here, would the following be satisfactory? I've included the full script of the attached item for a more comprehensive evaluation. The lengthy particle parameter shenanigans have been replaced by an ellipsis - I don't suppose they're relevant. (The little 'Say' script has been removed from the HUD since it is no longer required.)

CODE


list particle_parameters=[];

float SystemSafeSet = 0.00;

float SystemAge = 1.5;

StartParticles()
{
SystemSafeSet = SystemAge;
llParticleSystem([ ... ]);
llSleep(SystemAge);
SystemSafeSet = 0.00;
}

default
{
changed(integer change)
{
if(change & CHANGED_OWNER)
{
llResetScript();
}
}
state_entry()
{
SystemSafeSet = 0.00;
SystemAge = 1.5;
llListen(243, "", NULL_KEY, "");
}
listen(integer channel, string name, key id, string message)
{
if (llGetOwnerKey(id) != llGetOwner()) return;
{
llListen (243, "", NULL_KEY, "Message goes here");
}
StartParticles();
}
}



This appears to work when tested in the company of a few alts wearing similar items, although I haven't the experience to judge it's effect on lag.

Perhaps my problem is that I failed to make provision for changed owner and resetting the script?

I'm a little confused by your script. Why do you use a llListen function inside the listen event? llListen is just a function to tell the script to start listening. If you are inside the listen event, then your script is already listening to that channel. I think your script should be like this instead:
CODE
list particle_parameters=[];

float SystemSafeSet = 0.00;

float SystemAge = 1.5;

StartParticles()
{
SystemSafeSet = SystemAge;
llParticleSystem([ ... ]);
llSleep(SystemAge);
SystemSafeSet = 0.00;
}

default
{
changed(integer change)
{
if(change & CHANGED_OWNER)
{
llResetScript();
}
}
state_entry()
{
SystemSafeSet = 0.00;
SystemAge = 1.5;
llListen(243, "", NULL_KEY, "");
}
listen(integer channel, string name, key id, string message)
{
if (llGetOwnerKey(id) != llGetOwner()) return;
else if (message == "Put start command here") StartParticles();
}
}
_____________________
imakehuddles.com/wordpress/
Ethen Drechsler
Reanimated
Join date: 19 May 2008
Posts: 33
05-27-2008 22:58
From: Ziggy Puff
Uh oh, sharp intake of breath! I'm not sure if that's a good thing or a bad thing :)

Ah. No offense. The ZHAO is a wonderful contribution to SL, not least because it's open source. I could look at it all day.
From: Keiki Lemieux
llListen is just a function to tell the script to start listening. If you are inside the listen event, then your script is already listening to that channel.

Thanks for that advice, Keiki. I've taken the unnecessary llListen out as you suggest and the script works fine.

Any opinion on the use of listening channels (See above: 'One further question')? Would it make a difference if I had several objects listening for different messages on the same channel? Would it matter?
Keiki Lemieux
I make HUDDLES
Join date: 8 Jul 2005
Posts: 1,490
06-04-2008 10:11
From: Ethen Drechsler
If I have three items that run variations of the script, which are often but not always activated at the same time, would it be better to use different channels for each or not?

Note: I have been careful to do the '( age / rate ) * count' calculation on the particle emissions and minimise the respective particle counts.

Three items listening to the same channel doesn't sound very bad to me. The real question is how much information is being broadcast on that channel. For instance, if you are broadcasting lots of data and commands on that channel all the time, having multiple objects listening to it could be a problem. However, if you are just issuing commands to it every once in a while, it really shouldn't matter that much.
_____________________
imakehuddles.com/wordpress/