Jump to content

Detect Avatar vs Object? Seriously Frustrating...


Berksey
 Share

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

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

Recommended Posts

Okay, I've scoured the wiki and searched the forums, and I'm finding pretty much nothing on how to differentiate between an avatar and an ordinary physical object colliding with something. If it can be done, I know at least three people (not naming any names, I don't need to) here will know how to do it.

I can use the speed of the object to filter out avatars, because they only move so fast, but this is a dodgy workaround for my purposes. All I need is a way to prevent something happening if the collision is the result of an avatar bumping into my target object, but allow the event to occur if the target is hit by something other than an avatar.

I've tried several things so far, but with no success; it either stops all collision events or allows them all.

How (if possible) can I differentiate between whether the collision is with an avatar or just a moving object? I'm stumped! Is there any help for this?

Link to comment
Share on other sites

OMG, I tried it hours ago but with two &&'s... I was using AGENT_BY_USERNAME, though...

I'll try it the way you posted. Also, how would the llGetAgentSize work? If you know, just wondering is all... I like to know how things actually work when possible, so I know better what I'm doing with it all...

Either way, thanks so much for the quick reply, and I'll check back just in case!

EDIT: Issue Resolved. Thanks so much! I knew I could count on the Scripting Forum! ^-^ <3

Edited by Berksey
Link to comment
Share on other sites

It doesn't matter whether you use AGENT_BY_LEGACY_NAME or AGENT_BY_USERNAME.   The single ampersand is important, though.

As to the llGetAgentSize test, it's the standard way of seeing if an avatar is present on the region.   If llGetAgentSize can't read the avatar's size (either because the uuid is not that of an agent or if it is that of an agent,  the avatar isn't present on the region) it returns ZERO_VECTOR.  

Link to comment
Share on other sites

It also doesn't matter whether you use AGENT instead of AGENT_BY_LEGACY_NAME. Both are equivalent to 0x1 (which also means that you could write if(llDetectedType(0) & 0x1) if you really wanted to).  AGENT_BY_USERNAME is equivalent to 0x10, so not quite the same thing.  Since every avatar has both a legacy name and a username, though, it doesn't matter which of the three you use in this application.  In fact, if you ask your script to tell you what llDetectedType(0) returns, you find that it usually gives you 0x11, which covers all three.

Edited by Rolig Loon
Link to comment
Share on other sites

Nice!

Here's a little quandary I've been puzzling over, and it's related, so maybe there's something for it, as well.

When detecting an agent, and having determined it is, in fact an avatar, is it possible (without a gigantic wall of scripty innards being added to a 16-line script) to tell if the avatar is the prim owner? This might solve something I've been puzzling over for a looooong time, namely how to avoid a collision event on rezzing a projectile, without having to place it a distance away from myself (which would defeat my purposes in this specific case (prim-based close-up melee combat with particle effects)).

Just wondering, and thanks so much for the input, it's been incredibly helpful!

EDIT: I solved my own dilemma, but I'll leave the question and post what worked for me, just in case it helps anyone else...

if (llDetectedType(0) & AGENT & !OBJECT_OWNER)

^-^;

Edited by Berksey
  • Like 1
Link to comment
Share on other sites

  • 10 months later...

I have the exact opposite problem. I want my bumper to only be triggered by avatars, and not every time it bumps into an object or just walks over uneven ground. 

This is what I have so far, and it's way too sensitive:

string card = "batty";
key linecountid;
key lineid;
integer linemax;

integer random_integer( integer min, integer max )
{
  return min + (integer)( llFrand( max - min + 1 ) );
}


default
{
    state_entry()
    {
        //get the number of notecard lines
        linecountid = llGetNumberOfNotecardLines(card);
    }

    collision_start(integer num)
    {
        lineid = llGetNotecardLine(card, random_integer(0, linemax));
    }

    dataserver(key id, string data)
    {
        if (id == linecountid)
        {
            linemax = (integer)data - 1;
        }
        else if (id == lineid)
        {
            llSay(0, data);
        }
    }
}

 

to make it say random things in chat when someone bumps into me.

 

I've tried using  if(llDetectedType(0) & AGENT) but then nothing works at all anymore. :(

Edited by FPiepe
forgot to add something
Link to comment
Share on other sites

@FPiepe  The test if(llDetectedType(0) & AGENT) is the correct one.   The problem may be -- if you're wearing the attachment -- that it's constantly colliding with you.   If that's the case, then you'd need to loop through all the collisions, checking both that it's an agent and that the agent != llGetOwner().   Try

collision_start(integer num){
	if(llDetectedType(0) & AGENT){
		llOwnerSay(llGetDisplayName(llDetectedKey(0))+" just bumped into me.");
	}
}

To see what's happening.    There's no need, btw, to worry about ground collisions -- they register in a special land_collision* event, not the general collision* event.

Alternatively the problem could  be in the dataserver event .   i am not sure, because I wouldn't write a dataserver event that way, with no error handling.   If your card contains an empty line, for example, the script is going to fall over.   I would also read the notecard only once, to fetch all the lines, and store them in a list, and then read a random line from that list at turn runtime.
 

Link to comment
Share on other sites

Thank you. That works, but I have no idea how to get it to say the random lines then. And how do I store a list? Isn't that the same as a notecard? It did actually spam the random lines when I would just land or walk even, so I guess it was bumping into me. 

Link to comment
Share on other sites

I have this now, which works, sensitivity wise, but I know it needs a different command, to show only one random line from the list, and not show the whole list, just in random order:

 

list batty = ["? @_@ ? Price check on prune juice, Bob. Price check on prune juice.", "? @_@ ? And Frasier backs up and drop kicks two points!", "? @_@ ? Paging Billy's mommy. Please come to the Lost and Found.", "? @_@ ? There's a three mile traffic jam on the M25.", "? @_@ ? Now, back to you Sally.", "? @_@ ? LUCY!", "? @_@ ? Clean up on aisle 3"];
 
default
{
    collision_start(integer num_detected) 
    
    {
    if(llDetectedType(0) & AGENT){
        list shuffled = llListRandomize(batty, 1);
        llOwnerSay(llList2CSV(shuffled));
    }
}
}

Link to comment
Share on other sites

I did it! :D

list batty = ["? @_@ ? Price check on prune juice, Bob. Price check on prune juice.", "? @_@ ? And Frasier backs up and drop kicks two points!", "? @_@ ? Paging Billy's mommy. Please come to the Lost and Found.", "? @_@ ? There's a three mile traffic jam on the M25.", "? @_@ ? Now, back to you Sally.", "? @_@ ? LUCY!", "? @_@ ? Clean up on aisle 3"];
 
default
{
    collision_start(integer num_detected) 
    
    {
    if(llDetectedType(0) & AGENT){
         list randomizedList;
        
        //Randomize the List, and stuff in new variable
        randomizedList = llListRandomize(batty, 0);
        
        //Pull the first item from the randomized list
        llSay(0, llList2String(randomizedList, 0));
    }
}
}

 

In case anyone else needs it. Thank you so much for the head start. :)

Link to comment
Share on other sites

57 minutes ago, FPiepe said:

I did it! :D

That's great!  

Just for reference, this is how I would read a notecard and store the items in a list:

integer iCounter;
key kQuery;
key kNotecardUUID;
list lMyList;
string strNotecard;

default {
	state_entry() {
		strNotecard = llGetInventoryName(INVENTORY_NOTECARD, 0);
		if(llGetInventoryType(strNotecard)==INVENTORY_NOTECARD){//if there is a notecard in the object's inventory
			kNotecardUUID = llGetInventoryKey(strNotecard);//record the uuid
			kQuery = llGetNotecardLine(strNotecard,iCounter);//ask for the first line
		}
	}

	changed(integer change) {
		if(change & CHANGED_INVENTORY){
			if(llGetInventoryKey(llGetInventoryName(INVENTORY_NOTECARD, 0))!=kNotecardUUID){//the notecard has been replaced, removed or edited
				llResetScript();//try to re-read the notecard
			}
		}	
	}

	dataserver(key queryid, string data) {
		if(kQuery == queryid){//reply to query about the notecard
			if(EOF != data){//not reached the end of the file yet
				data = llStringTrim(data,STRING_TRIM);//trim leading and trailing spaces
				if(data != ""){//if there's anything left after removing spaces
					lMyList +=[data];//add it to lMyList
				}
				kQuery = llGetNotecardLine(strNotecard, ++iCounter);//advance the counter and ask for the next line
			}
			else{
				llOwnerSay("Finished reading the notecard");
			}
		}
	}
}

 

46 minutes ago, Love Zhaoying said:

Rolig’s Last post showed you how to get a random list entry without actually randomizing the list (which is much less efficient).

Rather than re-sort the list each time (or generate a random number) the way I usually do it is something like

integer max;
list lMyList = ["A","B","C"];
default
{
	state_entry()
	{
		max  = -llGetListLength(lMyList);//use negative indexing. that is, to quote the wiki on llList2String,
		//Negative indexes count from the far end, the first item being indexed as -length, the last as -1.
	}
	
	touch_start(integer num_detected) {

		llOwnerSay(llList2String(lMyList,max));
		if(!++max){//advance the value of max.  If it equals 0, then we've passed the end of the list
			llOwnerSay("Re-sorting the list");
			 max = -llGetListLength(lMyList); //then reset it 
			lMyList = llListRandomize(lMyList,1);//and reorder the list
		}

	}
}

That's just my alternative way of doing it, though.   I agree Rolig's method is the more usual one.

Link to comment
Share on other sites

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

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...