Only respond to chat commands from an object with the same owner...
|
|
Stig Olafson
Lemmy stole my sideburns.
Join date: 31 Jan 2005
Posts: 84
|
02-13-2006 11:13
Hi and once again, I come seeking wisdom.
I am currently working on a new version of a vehicle, which includes a few switchable features. I want to set up a HUD attachment to allow these to be easily switched whilst driving. But... it occurred to me that if two or more people are within the 10 meter range of llWhisper, this could result in one person's HUD controls influencing another person's vehicle.
So, here's the question:
How do I set up a listen to only respond to commands from another object that has the same owner?
First wonderful person to give me the answer gets one of the vehicles, when I've got it all working in good order. And thanks in advance...
_____________________
There is no right time, there is only now.
|
|
Adman Drake
Registered User
Join date: 9 Feb 2006
Posts: 96
|
02-13-2006 11:20
From: Stig Olafson
How do I set up a listen to only respond to commands from another object that has the same owner?
If I understand you correctly... You can specify who you want to listen to, but it's very limited. You can only specify a name (or id) of who's talking, what they are saying, or both. You can't tell who the owner of the talking object is. So, I think you need to listen to everyone. In your listen block, you'll get the ID of the thing that talked as a parameter. From there, you need to get the owner of that ID using llGetOwnerKey(key id). Compare that owner with the owner of the object, and if they match, then do what you want to do. Does that make sense? Something like this... Unfortunately, I think you have to listen to everyone... From: someone llListen(0, "", "", "spoken command goes here"  ; listen(integer channel, string name, key id, string message) { // compare owner of id with owner of this object if(llGetOwnerKey(id) == llGetOwner()) { // do stuff here } } Adman
|
|
Rizado DaSilva
Merchant
Join date: 12 May 2005
Posts: 30
|
02-13-2006 11:37
If the object is linked to the other, use llMessageLinked and link_message to send/recieve the commands, if not, then use llSay(chan_num,message) to send the command, where chan_num can be 0-9999999999 (not sure how high this goes, see wiki, but pretty big) - use any channel that ISN'T channel 0. Then listen with llListen(chan_num, "", "", ""  ; =R
|
|
Adman Drake
Registered User
Join date: 9 Feb 2006
Posts: 96
|
02-14-2006 14:20
From: Stig Olafson First wonderful person to give me the answer gets one of the vehicles, when I've got it all working in good order. And thanks in advance...
So... did this work? Did I win? Even a "thank you"...? Adman
|
|
Aliasi Stonebender
Return of Catbread
Join date: 30 Jan 2005
Posts: 1,858
|
02-14-2006 16:40
From: Stig Olafson Hi and once again, I come seeking wisdom.
I am currently working on a new version of a vehicle, which includes a few switchable features. I want to set up a HUD attachment to allow these to be easily switched whilst driving. But... it occurred to me that if two or more people are within the 10 meter range of llWhisper, this could result in one person's HUD controls influencing another person's vehicle.
So, here's the question:
How do I set up a listen to only respond to commands from another object that has the same owner?
First wonderful person to give me the answer gets one of the vehicles, when I've got it all working in good order. And thanks in advance... One way would be to have the HUD itself transmit the UUID of the owner with every command, and have the vehicle compare the key portion of the message with llGetOwner(). A really sneaky way to do this would be to have the HUD rename itself when attached to the owner to the owner's UUID. Have the vehicle listen only to objects named (string)llGetOwner(). Just make sure to have the HUD rename itself back when done. NOW WITH EXAMPLE! this goes in the HUD object: default { attach(key id) { if (id == NULL_KEY) { llSetObjectName("Object"); } else { llSetObjectName((string)llGetOwner()); } } touch_start(integer num) { llSay(0, "Message sent."); } }
This goes in the other object: default { state_entry() { llListen(0, (string)llGetOwner(), NULL_KEY, ""); }
listen(integer channel, string name, key id, string message) { llSay(0, "Message received."); } }
This demonstrates the principle.
_____________________
Red Mary says, softly, “How a man grows aggressive when his enemy displays propriety. He thinks: I will use this good behavior to enforce my advantage over her. Is it any wonder people hold good behavior in such disregard?” Anything Surplus Home to the "Nuke the Crap Out of..." series of games and other stuff
|
|
Stig Olafson
Lemmy stole my sideburns.
Join date: 31 Jan 2005
Posts: 84
|
03-27-2006 14:00
Sorry the reply has taken so long.... I haven't been on much at all.
Thanks both for your time and effort. Unfortunately, as soon as I transfer any of these, it all goes wrong. They still only listen to my transmitters, even though debug functions I added tell me they should be listening for other peoples' (their actual owners)!
Arrrgh!
_____________________
There is no right time, there is only now.
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
03-27-2006 14:43
You probably did something like "owner = llGetOwner" in state_entry. That got called the first time the script was (re)compiled, and set "owner" to your key. But after the object changed hands, that line never gets called again, so "owner" is still set to you.
There are multiple ways to solve this. You could put that line in on_rez, so the owner variable is reset every time the object rezzes, and will therefore pick up the new owner the first time the nest person uses it. Then there's something in the changed event that you can use too, but I wasn't 100% sure I understood how it worked, so I haven't used it.
|
|
Rodrick Harrington
Registered User
Join date: 9 Jul 2005
Posts: 150
|
03-27-2006 15:15
easiest to understand way I've done is keep the key of the owner, and on_rez, check the key against llGetOwner() if not equal llResetScript() if appropriate, or llRemoveListen and re-issue the listener (whatevers most appropriate to your code)
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
03-27-2006 15:37
That's true, you'd need to create a new listener too. Forgot about that 
|
|
Adman Drake
Registered User
Join date: 9 Feb 2006
Posts: 96
|
03-27-2006 15:38
From: Ziggy Puff You probably did something like "owner = llGetOwner" in state_entry. That got called the first time the script was (re)compiled, and set "owner" to your key. But after the object changed hands, that line never gets called again, so "owner" is still set to you.
Why would you make a variable called "owner" and assign it the results from llGetOwner()? Why not use llGetOwner() all over the place? Adman
|
|
Aliasi Stonebender
Return of Catbread
Join date: 30 Jan 2005
Posts: 1,858
|
03-27-2006 16:43
From: Adman Drake Why would you make a variable called "owner" and assign it the results from llGetOwner()? Why not use llGetOwner() all over the place?
Adman I believe it's slightly faster to reference the variable than constantly call the function, but one of the real LSL wizards like Strife would have to call me on that one.
_____________________
Red Mary says, softly, “How a man grows aggressive when his enemy displays propriety. He thinks: I will use this good behavior to enforce my advantage over her. Is it any wonder people hold good behavior in such disregard?” Anything Surplus Home to the "Nuke the Crap Out of..." series of games and other stuff
|
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
03-27-2006 22:47
In lay-person's language it's faster and saves memory...
Checking llGetOwner() takes the memory of the function call AND the return each time, and actually looks it it up each time too. Calling it once and storing it as a variable the data is there and directly accessible.
There's a much, much more technically correct description too, but I'm not really competent to give it.
|
|
Nepenthes Ixchel
Broadly Offended.
Join date: 6 Dec 2005
Posts: 696
|
03-27-2006 23:28
Adman is right. Sending the owner key in the message is easy faked. Make an open listener on whatever obscure channel you are using, and in the listen handler, use
if (llGetOwner()==llGetOwnerKey(_messagesender)
Don't do this on channel 0; open listeners on channel 0 are bad. Pick a channel like -78946121 instead.
|
|
Stig Olafson
Lemmy stole my sideburns.
Join date: 31 Jan 2005
Posts: 84
|
03-29-2006 14:08
Wow... thanks for all this.
I'm about to log on and try it out.
All those who contributed so far will get a version of the finished product, if I'm able to get it working now.
Thanks again.
_____________________
There is no right time, there is only now.
|
|
Stig Olafson
Lemmy stole my sideburns.
Join date: 31 Jan 2005
Posts: 84
|
03-29-2006 15:09
Wooohoooo!
It works now.
So, with this ready to implement, the new product should be done by this time next week, when all of you helpful people will receive a token of my thanks.
_____________________
There is no right time, there is only now.
|
|
Adman Drake
Registered User
Join date: 9 Feb 2006
Posts: 96
|
03-29-2006 15:18
From: Eloise Pasteur In lay-person's language it's faster and saves memory...
Checking llGetOwner() takes the memory of the function call AND the return each time, and actually looks it it up each time too. Calling it once and storing it as a variable the data is there and directly accessible.
There's a much, much more technically correct description too, but I'm not really competent to give it. I agree with this in theory, but in most cases, I'd guess that the difference in time/memory of making four or five GetOwner() calls instead of one call will be vastly overshadowed by other factors (ie, network latency). And as it's been pointed out, assigning the owner once and then transferring the object to someone could cause problems of varying significance.... I think I'll continue to use GetOwner... Adman
|
|
Nepenthes Ixchel
Broadly Offended.
Join date: 6 Dec 2005
Posts: 696
|
03-29-2006 18:35
From: Adman Drake And as it's been pointed out, assigning the owner once and then transferring the object to someone could cause problems of varying significance....
I use this: changed (integer change) { if (change & CHANGED_OWNER) { // give a notecard with instructions to the new owner //Reset listener. Or reset the entire script if you want. } }
|
|
Aislin Wallaby
Registered User
Join date: 4 Mar 2005
Posts: 27
|
Another solution
03-29-2006 19:07
Another solution that I'm using for almost the exact same application is to do something like this:
string hudname="name of my HUD object that's talking"; integer channel; default { state_entry() { string intermediate = (string)llGetOwner(); //we have to do it this way because you cannot explicity typecast a key into an integer channel=(integer)intermediate; //but you can typecast a string into an integer :P llListen(channel,hudname,NULL_KEY,""); }
listen(integer channel, string name, key id, string message); { //Do your stuff here } on_rez(integer value) { llResetScript(); } change(integer changed) { if (change & CHANGED_OWNER) { llResetScript(); } } }
this seems like a few extra lines, but it avoids the owner change issues that were listed below and will double check on rez in case the owner's key gets changed. Use a similar call in the HUD to set its listen channel and swap out the HUD name for the vehicle's name if they need to talk back and forth. This also allows for each AV's HUD to be talking on its own channel to prevent any sort of channel congestion if you have multiple AVs in an area with multiple HUDs. For those of you who are picky, pretty much everyone's key starts with a 5 digit number and typecasting a string into an integer will basically take the first five digits of key, leaving 99,999 possible channels and thus a 1 in 99,999 chance of being near someone with the same key (possible, but not likely). If you want to get even trickier, you can add in a llKey2Name call and set the name of the HUD as being unique based on the avatar's name as well (I know Cubey does this with his vehicles apparently on a CHANGED_OWNER event). If you're really paranoid, you can also make sure that the key doesn't start with 00001 as well....hmmm, maybe I'll do that, just in case
|