Jump to content
Sign in to follow this  
Extraneousnomenclature

Getting a script to respond to a word within a phrase ...

Recommended Posts

OK, this script works fine when someone says "hello." It says hello right back.
But what if someone says "hello there" or "I just wanted to say hello" or something like that.
How do I change the script so it responds to "hello" embedded in a phrase?

default
{
    state_entry()
    {
        llListen(0,"","","");
    }
    listen(integer channel,string name, key id, string msg)
    {
        if (msg == "hello")
        {
            llSay(0, "hello");
        }
    }
}

 

Share this post


Link to post
Share on other sites

Use llSubStringIndex, which is designed to tell you where a particular substring is within a longer string. For example,

integer i = llSubStringIndex(message, "hello");

will tell you where the substring "hello" lies in message.   If it isn't there at all, i will be equal to -1.  So, a test for

if (llSubStringIndex(message,"hello") != -1)

will succeed if "hello" is found and will fail if it isn't.  Remember, of course, that "hello" is not the same as "Hello" or "HELLO", so you'll have to do some filtering to start using the function wisely.  Still, that's the basic idea.

  • Like 1

Share this post


Link to post
Share on other sites
Thanks!That worked, and I can finally faintly glimpse the logic.I had puzzled over llSubStringIndex in the LSL wiki without being able to figure out how to apply it.And yes, now on to figure out llToLower or whatever that good stuff is that will let me say "Hello "default{    state_entry()    {        llListen(0,"","","");    }    listen(integer channel,string name, key id, string msg)    {       if (llSubStringIndex(msg,"hello") != -1)        {            llSay(0, "hello");        }    }}        

 

Share this post


Link to post
Share on other sites

I not know if this what you intend, but anyone or any object in the sim that says hello on the public_channel will output hello from your script. ADDED: Well depending on the braodcast range that being used. Also you will have to run three passes to cover different upper case and lower case possibilities, else the whole message will have to be converted.

Share this post


Link to post
Share on other sites

Just out of curiousity is this way better?

default{    state_entry()    {        llListen(0,"","","");    }    listen(integer channel,string name, key id, string msg)    {       if (~llSubStringIndex(llToLower(msg),"hello"))        {            llSay(0, "hello");        }    }}

 

 

Share this post


Link to post
Share on other sites

Yes, of course, but I was letting the OP discover that and a number of other things for herself.  She'll probably learn better that way.  She's doing OK so far.  :smileywink:

Share this post


Link to post
Share on other sites


Rolig Loon wrote:

Yes, of course, but I was letting the OP discover that and a number of other things for herself.  She'll probably learn better that way.  She's doing OK so far.  :smileywink:

Will Rogers said, "There are three kinds of men. The one that learns by reading. The few who learn by observation. The rest of them have to pee on the electric fence for themselves."

What Will Rogers neglected to mention is that peeing on the electric fence is still the fastest way for readers and observers to learn. And that, with a suitable substitution (in my case it was touching an electric fence with a buttered piece of bread), this applies to women as well.

;-)

Share this post


Link to post
Share on other sites

Steph,

Rolig was suggesting that people learn better by actually trying things, rather than being shown the way. And that's why she was holding back and not showing the OP how to do it.

The famous American humorist Will Rogers made the wry observation that some people may learn only by doing, and that you probably can't show or tell them anything. That was not what Rolig was suggesting, though I think we've all met people who are a little like that, or we have been someone who is a little like that.

You wouldn't have to search very hard to find someone who thinks that trying to teach me is pointless.

;-)

Share this post


Link to post
Share on other sites

Can I change the word the script is looking for to a veriable? Like by adding

 

list greeting = hello,hi,hey,morning;

then changing the listen line like this

(~llSubStringIndex(llToLower(msg),greeting))

Share this post


Link to post
Share on other sites

No.  You'd need to test each one of your possible greeting words separately, which is going to be slow.  Also, because you are leaving the llListen open, the script will continue to do all of that work whenever anyone says anything within chat range, thus adding a significant chat lag to the sim.  You can lose a lot of friends for doing this.  The only time I could justify using something like this script would be, for example, if you had a password-protected doorway that expected a chat keyword within a few seconds after you step on the doormat.  So, something like ....

 

list gGreeting = ["hello","hi","hey","morning"];integer gLsn;default{    collision_start(integer num)    {        llSetTimerEvent(10.0);        gLsn = llListen(0,"",llDetectedKey(0),"");    }    listen(integer channel,string name, key id, string msg)    {       llListenRemove(gLsn);       llSetTimerEvent(0.0);       integer i;       while(i < llGetListLength(gGreeting))       {           if (~llSubStringIndex(llToLower(msg),llList2String(gGreeting,i)))          {            llSay(0, "hello");          }          ++i;       }    }    timer()    {        llSetTimerEvent(0.0);        llListenRemove(gLsn);    }}

 

 

 

 

Share this post


Link to post
Share on other sites

There are a few ways to speed up things....

 

All the greetings have different starts.  Do your comparisons on a substring (in this case, the first 2 characters differ in every greeting in the list) so the comparisons execute faster.  Not a lot in this particular case, but for more extensive lists it can add up quickly.

 

Open listens on the public channel are potentially lag monsters.  Do like Rolig says, and only open it when someone gets close by (use a sensor or a collision volume or collision object) then close it after a timeout.  There are potential cases where it will then not work correctly (the avi enters, but doesn't say anything before the timeout.)  A repeat sensor with a long time between refreshes (the same as the timeout of the timer, or a little less) that keeps the listen from being removed if someone is still in range.

 

Or just put a keypad and require entering a code.  Or have a listen on a non-public channel that the users you want to be able to enter are given and only listen on that (and maybe an object they can use that will echo what they type onto that channel when active.)

 

Lots of potential workarounds to avoid lag and poor responsiveness.

 

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...