Jump to content

Listener that repeats message in nearby chat to owner only if the owner is further than 20 m from whoever/whatever sent the message


You are about to reply to a thread that has been inactive for 1523 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Posted (edited)

This is a script that will repeat anything that it hears in nearby chat within 20m to the owner. This script will be in an object within range of a few people. If I'm already in range of the person who sent the chat, it will repeat it to me twice, which is unfavourable. How do I detect if the person who sent the chat in nearby is already within 20 metres of the owner (me)? If I could add an if statement around the llOwnerSay() that only repeats a message when I'm out of the 20 m range of the avatar or object that sent it, that'd be great.

integer nearby;
 
default
{
    state_entry()
    {
        nearby = llListen(0, "", "", "");
    }
 
    listen(integer channel, string name, key id, string message)
    {
        llOwnerSay(message);
    }
}

 

Edited by Leo1452
Posted (edited)

Interesting question because if the script is attached to you and if it can only hear chat within 20m, and if you set it to ignore anything within 20m, then everything it hears will fall into the 20m range and thus be ignored.

Nevertheless, to get the distance of the avatar speaking, use "list details = llGetObjectDetails(id, [OBJECT_POS])" to get their position.  "id" is the key of the avatar returned by the listen() event.  That function will return a single-item list, so convert to vector using "vector pos = llList2Vector(details, 0)".  Then, do "float distance =  llVecDist(llGetPos(), pos)"  with llGetPos() as your position.  "If (distance >  20.0) llOwnerSay()".

Edited by DoteDote Edison
  • Like 1
Posted
14 minutes ago, DoteDote Edison said:

Interesting question because if the script is attached to you and if it can only hear chat within 20m, and if you set it to ignore anything within 20m, then everything it hears will fall into the 20m range and thus be ignored.

Nevertheless, to get the distance of the avatar speaking, use "list details = llGetObjectDetails(id, [OBJECT_POS])" to get their position.  "id" is the key of the avatar returned by the listen() event.  That function will return a single-item list, so convert to vector using "vector pos = llList2Vector(details, 0)".  Then, do "float distance =  llVecDist(llGetPos(), pos)"  with llGetPos() as your position.  "If (distance >  20.0) llOwnerSay()".

Hi. Sorry, I shouldn't have said the object is attached to me. Let's say that the object is on the ground. How can it know the distance between me and the person/object that just spoke?

Posted

Ah, that makes more sense.  The process would be the same, just replace the llGetPos() in llVecDist with a second call to llGetObjectDetails(), only using your own id instead of the id from the listen() event.  Basically, store your id/key into a global variable when the script starts using llGetOwner().  Each time the script hears something, get your position and the position of the speaker using llGetObjectDetails(), and use llVecDist() to get the distance between your position and the person speaking.

Posted (edited)
integer nearby;

default
{
    state_entry()
    {
        nearby = llListen(0, "", "", "");
    }

    listen(integer channel, string name, key id, string message)
    {
        list id_details = llGetObjectDetails(id, [OBJECT_POS]);
        vector id_position = llList2Vector(id_details, 0);

        list owner_details = llGetObjectDetails(llGetOwner(), [OBJECT_POS]);
        vector owner_position = llList2Vector(owner_details, 0);

        if (llVecDist(id_position, owner_position) > 20)
        {
            llOwnerSay(message);
        }
    }
}

Or, just to make things a little less repetitive, we can turn the llGetObjectDetails thing into a reusable function.

integer nearby;

vector GetKeyPos(key id)
{
    list id_details = llGetObjectDetails(id, (list)OBJECT_POS);
    return llList2Vector(id_details, 0);
}

default
{
    state_entry()
    {
        nearby = llListen(0, "", "", "");
    }

    listen(integer channel, string name, key id, string message)
    {
        vector something = GetKeyPos(id);
        vector owner = GetKeyPos(llGetOwner());

        if (llVecDist(something, owner) > 20)
        {
            llOwnerSay(message);
        }
    }
}

 

Edited by Wulfie Reanimator
  • Like 3
Posted
2 hours ago, Wulfie Reanimator said:

Or, just to make things a little less repetitive, we can turn the llGetObjectDetails thing into a reusable function.

 

One thing to remember, handle if changed owner, this makes it easier to distribute.

    changed(integer change)
    {
        if (change & CHANGED_OWNER)
        {
            llResetScript();
        }
    }

And always be aware llListen(0, "", NULL_KEY,"") used in a busy sim with a lot of people coming and going can contribute to lag of sim.

Posted (edited)
19 minutes ago, Rachel1206 said:

One thing to remember, handle if changed owner, this makes it easier to distribute.

This doesn't need to be taken into account in the script I posted, because the value is consumed immediately and never stored anywhere.

If, instead, you were to create a listen with llListen(0, "", llGetOwner(), ""), you would cause problems because the listener would stay open (meaning, listening to the original owner) even when the object is transferred if the script was not reset.

Edited by Wulfie Reanimator
You are about to reply to a thread that has been inactive for 1523 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...