Listener
|
|
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
|
04-05-2006 14:34
So, I wrote a script, (with help from the LSL wiki), that looks for a notecard called "Channel" which has a single integer in it; the channel that the listener is listening for. It worked right after I compile it and make the notecard channel 0, but when I change it to channel 2, it doesn't work right? What is wrong? string gName = "Channel"; // name of a notecard in the object's inventory integer gLine = 0; integer chan; // current line number key gQueryID; // id used to identify dataserver queries
default { state_entry() { gQueryID = llGetNotecardLine(gName, gLine); // request first line }
dataserver(key query_id, string data) { if (query_id == gQueryID) { llListen((integer)data,"",NULL_KEY,""); integer chan = (integer)data; } } listen(integer channel, string name, key id, string message) { if (channel == chan) { llOwnerSay("Channel " + (string)chan + ": " + message); } } }
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
04-05-2006 14:56
The "integer chan" in the dataserver event shadows the global integer chan, so the global never gets set, and stays 0. That's why it only works when the notecard contains 0. Change this line: integer chan = (integer)data; To: chan = (integer)data; That will update the global, and it should work. You are resetting the script after changing the notecard, right? I think there's a way to automatically detect if the notecard's contents have been changed. I think it's the change event, and the event will be CHANGED_INVENTORY. Or something like that. Might be useful for a script like this. If you use it, reset the script when you detect the changed notecard, or better, close the old listener and open a new listener. To do that, you'll have to save the return value of the llListen call (the listener's handle) into a variable, so you can use it with llListenRemove later.
|
|
Baron Hauptmann
Just Designs / Scripter
Join date: 29 Oct 2005
Posts: 358
|
04-05-2006 15:01
The only time the script reads the notecard is when it is first rezzed. There is essentially no other time that it will go through state_entry. So it never reads the notecard again after it is initialized. You can reset this script after you change the notecard and it will work. If you plan on the notecard being changed periodically, you need to work this into the script, reading the notecard somewhere other than state entry. Hope that helps. Baron EDIT: was writing while Ziggy posted. . . yeah, and what he said 
|
|
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
|
04-05-2006 15:14
Lol thanks for the info, that one works now. But, I need help with another  Here's a scirpt that I wanted to listen for the word "listen" on channel 2 PLUS an integer, and it changes the channel that it listens for and says what it hears on that channel. Sorry, it's a bit messy. integer chan; default { state_entry() { llListen(2, "", llGetOwner(), ""); }
listen(integer channel, string name, key id, string message) { if (message == "reset") { llResetScript(); } if (llGetSubString(message, 0, 2) == "listen") { string object = llGetSubString(message, 7, -1); chan = (integer)object; llOwnerSay("Listening to channel " + (string)chan); if (chan == chan) llListen(chan,"",NULL_KEY,""); if (message == message) llOwnerSay("Channel " + (string)chan + ": " + message); } } }
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
04-05-2006 15:17
if (llGetSubString(message, 0, 2) == "listen") "listen" is 6 characters, so you need indices 0 - 5, not 0 - 2. llGetSubString(message, 0, 2) will give you "lis", which will never be equal to "listen". if (chan == chan) if (message == message) What are those for? A variable will always be equal to itself.
|
|
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
|
04-05-2006 15:24
I wanted to have them trigger events, so when (message == message), it does the event. I tried your suggestion, and it only listens once, and never listens again.
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
04-05-2006 15:39
Well, "if (message == message)" will always return true. No matter what the value of message is, it will always be equal to itself. So anything inside that if check will always execute, which is equivalent to removing the if check and just putting that code in there. When you say it doesn't listen after the first one... you did try issuing the second command on the new channel, right? And I would remove the old listener before creating a new listener, like I said in a previous post, or you'll eventually run out of listeners and crash. integer gChannel; integer gHandle;
default { state_entry() { gHandle = llListen(gChannel, "", llGetOwner(), ""); }
listen(integer channel, string name, key id, string message) { if (message == "reset") { llResetScript(); }
if (llToLower(llGetSubString(message, 0, 5)) == "listen") { gChannel = (integer)llGetSubString(message, 7, -1); llOwnerSay("Switching to channel " + (string)gChannel);
llListenRemove(gHandle); gHandle = llListen(gChannel,"",NULL_KEY,""); } } }
Something like that.
|
|
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
|
04-05-2006 15:42
This one actually works worse then mine 0_0. It doesn't listen at all. Thanks for the really neat try though 
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
04-05-2006 15:47
I think I'm misunderstanding you. This script starts out listening on channel 2. To make it switch channels, you'll need to type in, as an example: From: someone /2 listen 45 That will make it say: From: someone Switching to channel 45 And it will now be listening on channel 45. to make it switch again, you'll have to now type in: From: someone /45 listen 73 Which will make it say: From: someone Switching to channel 73 ... and so on. Unless I totally messed the script up  Of course, all the script does is change channels, it doesn't do anything else. So you'll need to put in code to actually make it do something in addition to changing channels. Anyway, like I said, I think I misudnerstood what you were trying to do, so feel free to ignore everything I said 
|
|
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
|
04-05-2006 16:11
Here, I got mine ALMOST working. This is almost what I wanted. I can change the channel anytime by saying "/2 listen [CHANNEL HERE]", even if I'm already listening to another channel. The only bad thing is that it keeps listening to the one before it. How would I make it so it only listens to the current one, and still allows me to use the command "/2 listen [CHANNEL HERE]" to change the channel? Would I have to use "jump" to events? integer chan; default { state_entry() { llListen(2, "", llGetOwner(), ""); }
listen(integer channel, string name, key id, string message) { if (message == "reset") { llResetScript(); } if (llGetSubString(message, 0, 5) == "listen") { string object = llGetSubString(message, 7, -1); chan = (integer)object; llOwnerSay("Listening to channel " + (string)chan); llListen(chan,"",NULL_KEY,""); } else llOwnerSay("Channel " + (string)chan + ": " + message); } }
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
04-05-2006 16:17
You really don't want to use that, because it sets up a new listen for every channel. What you want to do is use llListenRemove to get rid of the old listen each time you change. Have integer gLId = 0; at the top and, instead of llListen(chan,"",NULL_KEY,""  , have if (gLId != 0) llListenRemove(gLId); gLId = llListen(chan,"",NULL_KEY,"");
|
|
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
|
04-05-2006 16:23
Like this? It doesn't seem to work. integer chan; integer gLId = 0; default { state_entry() { llListen(2, "", llGetOwner(), ""); }
listen(integer channel, string name, key id, string message) { if (message == "reset") { llResetScript(); } if (llGetSubString(message, 0, 5) == "listen") { string object = llGetSubString(message, 7, -1); chan = (integer)object; llListen(chan,"",NULL_KEY,""); llOwnerSay("Listening to channel " + (string)chan); if (gLId != 0) { gLId = llListen(chan,"",NULL_KEY,""); llListenRemove(gLId); } else llOwnerSay("Channel " + (string)chan + ": " + message); } } }
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
04-05-2006 16:28
You want to also replace
llOwnerSay("Channel " + (string)chan + ": " + message);
with
llOwnerSay("Channel " + (string)channel + ": " + message);
but otherwise it works fine for me. It will also report anything said on channel 2 that's not "listen 23423423". If you don't want to do that, replace the above with
if (channel != 2) llOwnerSay("Channel " + (string)channel + ": " + message);
|
|
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
|
04-05-2006 16:36
Took your advice. Here's the finished copy  THanks for the help. integer chan; integer listen1; default { state_entry() { llListen(2, "", llGetOwner(), ""); }
listen(integer channel, string name, key id, string message) { if (llGetSubString(message, 0, 5) == "listen") { string object = llGetSubString(message, 7, -1); chan = (integer)object; llOwnerSay("Listening to channel " + (string)chan); llListenRemove(listen1); llListen(chan,"",NULL_KEY,""); } else if (channel == chan) { llOwnerSay("Channel " + (string)channel + ": " + message); } if (message == "reset") { llResetScript(); } } }
|
|
Raster Teazle
Registered User
Join date: 13 Sep 2005
Posts: 114
|
04-10-2006 23:46
very entertaining thread...  at least change this: llOwnerSay("Listening to channel " + (string)chan); llListenRemove(listen1); llListen(chan,"",NULL_KEY,"");
to this: llOwnerSay("Listening to channel " + (string)chan); llListenRemove(listen1); listen1 = llListen(chan,"",NULL_KEY,""); // save the new listen handle here!
|
|
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
|
04-11-2006 04:00
Lol okey dokey, Raster. I'm glad I was able to entertain you.
|