Jump to content
Sign in to follow this  
Ravenmists

Help with collision script to ignore avatars but respond to anything else

Recommended Posts

Hi, im trying to figure out how to correctly use the llDetectedType function so that in a collision event it will ignore avatars but will respond to any other object it collides with. I have tried everything from the sensible to the not so sensible like if(llDetectedType(0)!=AGENT_BY_LEGACY_NAME) or if(llDetectedType(0)!=AGENT_BY_LEGACY_NAME|ACTIVE) or if(llDetectedType(0)!=AGENT_BY_LEGACY_NAME&ACTIVE) of if(!llDetectedType(AGENT_BY_LEGACY_NAME&ACTIVE) etc etc etc.

 

Can anyone provide me with a working example that ignores avatars but responds to anything else on collision?

 

ty ^_^_^_^_^_^_^

Share this post


Link to post
Share on other sites

I see a couple potential problems here.

First, there are three collision events. collision_start(), collision_end(), and collision(). They do what they sound like -- collision_start() is triggered when a collision begins, while the item is colliding (eg, pushing against the prim) the collision() event will fire something like every 0.05 seconds (or 0.1-ish probably), and when the colliding object finally goes away collision_end() will fire. You simply mentioned "collision event", so if you're not certain you're using the right one (or combination thereof), you can outline what it is you're making and we can help with that.

Second, you're using a (very useful) shortcut, but which can be dangerous in this case. llDetectedType(0), using a zero, assumes that only one item is colliding. If more than one is colliding, you will only be checking against the first item in the list of colliding items. If you're doing something like a touch_start() event in a HUD, you can almost guarantee only one person will ever be touching it, and can save some effort by using this shortcut. However, in this case you probably don't want to do that.

To find the problem, I recommend outputting some debug information. You can use the following script to see what's actually going on, rather than shooting into the darkness and hoping you hit something. Then use the information to make whatever it is you're trying to make.

// Debug style output for collision events.string returnType(integer i) {    string s;    if (i & AGENT_BY_LEGACY_NAME) {        s += "AGENT ";    }    if (i & ACTIVE) {        s += "ACTIVE ";    }    if (i & PASSIVE) {        s += "PASSIVE ";    }    if (i & SCRIPTED) {        s += "SCRIPTED ";    }    return s;}// Modified LSL library functionstring int2hex(integer iInt, integer iLen) {    string s;    do {        s = llGetSubString("0123456789ABCDEF", iInt & 0x0000000F, iInt & 0x0000000F) + s;        iInt = iInt >> 4;    } while (iLen = ~-iLen);    return s;}default {    collision_start(integer x) {        llOwnerSay((string)llGetTime()+": collision_start("+(string)x+") triggered.");        while (x--) {            integer iType = llDetectedType(x);            string sName = llDetectedName(x);            string s = returnType(iType);            llOwnerSay((string)x+" ("+sName+") is type "+s+" (0x"+int2hex(iType,4)+")");        }    }    collision(integer x) {        llOwnerSay((string)llGetTime()+": collision("+(string)x+") triggered.");        while (x--) {            integer iType = llDetectedType(x);            string sName = llDetectedName(x);            string s = returnType(iType);            llOwnerSay((string)x+" ("+sName+") is type "+s+" (0x"+int2hex(iType,4)+")");        }    }    collision_end(integer x) {        llOwnerSay((string)llGetTime()+": collision_end("+(string)x+") triggered.");        while (x--) {            integer iType = llDetectedType(x);            string sName = llDetectedName(x);            string s = returnType(iType);            llOwnerSay((string)x+" ("+sName+") is type "+s+" (0x"+int2hex(iType,4)+")");        }    }}

Third, and this is probably the actual solution now that I think about it, you're mixing comparison and bitwise operations, but not in the right way.

llDetectedType(0) != (AGENT_BY_LEGACY NAME | ACTIVE) should have worked (for any agent not sitting on something, I think). I'm not sure if the bitwise and (pipe, |) is evaluated before or after the "not equal to" (!=) operator. So when in doubt, add parenthesis. Also add them for readability when it's confusing.

The following would match any avatar collision:

llDetecectedType(0) & AGENT_BY_LEGACY_NAME

Which means this would match any non-avatar collision:

!(llDetecectedType(0) & AGENT_BY_LEGACY_NAME)

For more information on how bitwise operators work, check out the entries near the bottom of the table here: http://wiki.secondlife.com/wiki/LSL_Operators and then check out the last section of the page. Understanding how to build your conditions and how to use flags or masks is important.

Share this post


Link to post
Share on other sites

How about this (off the top of my head and untested)?

 

	collision_start(integer total_number)	{		integer i;		do {			if(llDetectedType(i)&AGENT_BY_LEGACY_NAME){				//don't do anything			}			else{				llOwnerSay(llDetectedName(i)+", which is not an agent, collided with me");			}		}		while (++i<total_number);	}

 

  • Like 1

Share this post


Link to post
Share on other sites

thankyou both for replying, some useful information there and yes im not so up to date with bitwise, im still learning what they do and how to use the correctly and efficately. Ima look at that now :)

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...