Just an additional comment re the changed() event:
A common use for this event trigger is to detect when someone sits down on a prim or stands up again. There is a bug in the code that results in the changed() event NOT being triggered when it has a current sit target = <0.0,0.0,0.0>, ZERO_ROTATION. There is no mention made of this bug in the SL scripting wiki in any of the relevant wiki articles so you won't find this documented in the changed() article or the CHANGED_LINK article; and while the llSitTarget article mentions that setting it to <0.0,0.0,0.0>,ZERO_ROTATION removes the sit target, it doesn't explicitly state that this results in the changed() event not being triggered when an avatar subsequently sits on it. I wasted a silly amount of time trying to debug an otherwise perfect script I wrote that didn't change the sit target to something other than the default null values.
Bottom line: if you want to use the changed() event to detect and avatar sitting down or standing back up again, you
must change the sit target at some other point in the script
prior to the point when you expect the avatar to sit down on it. Even setting it to <0.0,0.0,0.000001>, ZERO_ROTATION is enough top ensure that the changed() event triggers as expected.
If for some reason you absolutely must have the sit target set to NULL, there is another work-around for this bug: you can run a frequent (and therefore more resource-intensive) timer check to see how many prims are attached to the object using a comparison of the result of two prim-count functions. The llGetObjectPrimCount function doesn't include seated avatars in its count whereas the llGetNumberOfPrims function does, thus any difference in their counts *should* indicate that an avatar is sitting on the prim.
If you want to check this out for yourself, rez a prim and drop the following script in it. In its entry state only the the timer will notice and report it when you sit down on the prim or stand up again. If you touch the prim, both the changed() event and the timer will notice and report it to you. Touching the prim again will continue to toggle it back and forth between the two.
{L_CODE}:
vector currentSitTarget=ZERO_VECTOR;
integer targetFlag=FALSE;
key avatarID;
integer timerFlag=FALSE;
default
{
state_entry()
{
llSitTarget(currentSitTarget,ZERO_ROTATION);
llOwnerSay("Sit target now set to " + (string)currentSitTarget);
llSetTimerEvent(0.5);
llOwnerSay("Object prim count check reports " + llGetObjectPrimCount(llGetKey()));
llOwnerSay("Number of prims check reports " + llGetNumberOfPrims());
}
changed(integer change)
{
if (change & CHANGED_LINK)
{
avatarID = llAvatarOnSitTarget();
if (avatarID && avatarID!=NULL_KEY)
{
llOwnerSay(llKey2Name(avatarID) + " sat on me.");
}
else
{
llOwnerSay("The avatar stood up again.");
avatarID = NULL_KEY;
}
}
}
touch_start(integer num_detected)
{
if (targetFlag)
{
currentSitTarget = ZERO_VECTOR;
targetFlag=FALSE;
}
else
{
currentSitTarget = <0,0,0.000001>;
targetFlag=TRUE;
}
llSitTarget(currentSitTarget,ZERO_ROTATION);
llOwnerSay("Sit target now set to " + (string)currentSitTarget);
}
timer()
{
if (!timerFlag && llGetObjectPrimCount(llGetKey())!=llGetNumberOfPrims())
{
timerFlag=TRUE;
llOwnerSay("Timer routine detected an avatar sitting down");
}
else if (timerFlag && llGetObjectPrimCount(llGetKey())==llGetNumberOfPrims())
{
timerFlag=FALSE;
llOwnerSay("Timer routine detected an avatar standing up");
}
}
}
EDIT: This bug had been
reported in Mantis months ago but left unattended so I bumped it again yesterday. I notice that someone has since looked at it and that a fix should be coming (presumably with the next code update)