Don't click here unless you want to be banned.

LSL Wiki : changed

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl801.us.archive.org
changed(integer change)

The changed event is invoked when operations change certain properties of the prim/object. The change parameter is a bitfield of one or more of the following values:

Constant Value Indicates
CHANGED_INVENTORY 0x1 changed object inventory (could include an item being added, removed, or renamed, or a notecard being edited and saved). Details
CHANGED_COLOR 0x2 changed object color or transparency
CHANGED_SHAPE 0x4 changed object shape (box to cylinder, for example), cut, hollow amount/shape, twist, top size, or shear
CHANGED_SCALE 0x8 changed object scale. Details
CHANGED_TEXTURE 0x10 changed object texture: offset, repeats, rotation, and reflection/bump maps (but not transparency -- that's CHANGED_COLOR). Also triggered when the glow status of the object is changed.
CHANGED_LINK 0x20 linking or delinking (also when an avatar sits on or unsits from the object). Details
CHANGED_ALLOWED_DROP 0x40 An item was dropped (into this object's inventory) that was only allowed by the llAllowInventoryDrop function. This allows the object to identify items dropped by anyone who doesn't have modify permissions on the object.
CHANGED_OWNER 0x80 The ownership of the object changed. This value is passed when an object is deeded to a group, when an object is purchased, or when a newly-purchased object is rezzed. Details
CHANGED_REGION 0x100 The object changed regions/sims. Details
CHANGED_TELEPORT 0x200 The object has been teleported. Details
CHANGED_REGION_START 0x400 The region this object is in has just come online.
CHANGED_MEDIA 0x800 The prim media has changed.

These values are bitwise and can be ORed or ANDed together.
Two flags can show up in the same event trigger; it has been seen when resizing an object with the "Stretch Textures" box unchecked so the texture scale (repeats) changes as the prim is resized. Also, the CHANGED_REGION and CHANGED_TELEPORT seem to come in tandem.

With this in mind, always write "if (change & CHANGED_LINK)" rather than "if (change == CHANGED_LINK)" so that the contents of your event will be triggered in all cases. Likewise, using IF/ELSEs (as in "else if (change & CHANGED_SCALE)") could theoretically result in only one of the triggers being counted. If you stick to with IF statements only, your changed event will need to perform a check for each IF statement, but it will catch all triggers in the very rare event of a simultaneous trigger.


Notes:

Example:
// When an avatar sits on the object containing this script,
// the object will say "Get off!" and then force the avatar to stand up.
default {
    state_entry() {
        llSitTarget(<0, 0, 0.1>, ZERO_ROTATION); // needed for llAvatarOnSitTarget to work
    }
    
    changed(integer change) { // something changed
        if (change & CHANGED_LINK) { // and it was a link change
           // llSleep(0.5); // llUnSit works better with this delay
            key av = llAvatarOnSitTarget();
            if (av) { // somebody is sitting on me
                llSay(0, "Get off!"); // say in chat when person is remove from prim
                llUnSit(av); // unsit him
            }
        }
    }
}

Details

Constant or Value: changed() is triggered: changed() is not triggered:
CHANGED_INVENTORY
  • when adding any inventory item to the prim's inventory.
  • when deleting any inventory item from the prim's inventory.
  • when changing the name or description of an inventory item inside the prim.
  • when changing asset permissions of an inventory item within the prim.
  • when saving a notecard that already exists within the prim's inventory.
  • when recompiling a script that already exists in the prim's inventory.
  • when inventory is changed in another prim in the linked object.
  • when resetting a script.
  • when a no-copy item is removed (but not deleted!) from the prim by manually dragged back to user inventory.
  • when inventory is added using llAllowInventoryDrop, and the user dropping the new inventory item is not the owner of the prim.
  • when the change is invoked via LSL llRemoveInventory(..). This may be a bug, see: http://jira.secondlife.com/browse/SVC-304
CHANGED_SCALE
  • in a prim, linked or not, when resizing that prim. (as of 5/6/2008, resizing a child prim causes CHANGED_SCALE in the *root* prim -- LexNeva)
  • in the root prim in a linked object when resizing the entire object.
  • in a different prim in a linked object when resizing a separate prim in that object.
  • in a child prim in a linked object when resizing the entire object.
CHANGED_LINK
  • when linking two (or more) prims together.
  • when delinking an object.
  • when delinking a prim from an object.
  • when an avatar sits on an object.
  • when a sitting avatar stands up from the object.
  • when duplicating a linked object.
  • When changing the prim type/shape of a prim in the object.
  • in an attachment when an avatar sits down or stands up.
  • in an attachment when it's attached.
  • in an attachment when another attachment is attached.
  • in an attachment when you sit on an object.
  • in an object when the sitting avatar attaches an object.
  • when duplicating a single prim.
CHANGED_OWNER
  • in the original object when a user buys the object.
  • in the original object when a user buys a copy of the object.
  • in the original object when a user takes the object or a copy of the object.
  • in the newly-rezzed copy when the user rezzes the object for the first time. (on_rez() is still triggered first.) This occurs whether or not the object was copied or purchased.
  • when an object is deeded to a group.
  • in the original object when the user buys the contents of an object. It is still triggered in the copy when the new owner rezzes it.
CHANGED_REGION
  • in the root prim of an attachment when the user teleports to a new sim/region or crosses into a new sim directly.
  • in the root prim of an object that moves into a new region.
  • in a child prim of an attachment when the user teleports to a new region.
  • in a child prim of an object that moves into a new region.
  • after taking the object into inventory, moving/teleporting to a new region and rezzing it there - it is only triggered if the object moves into a new region while it is rezzed
CHANGED_TELEPORT
  • in the root prim of an attachment when the user teleports to a new sim, or a location within the current sim. This happens whether they teleport manually, or using one of the teleport functions.
  • in a child prim of an attachment when the user teleports to a different location.
  • in any prim in an attachment when the user sits on an object that uses the llSitTarget "sit teleport" trick.
  • in any prim in an unattached object.
  • in an attachment, after teleporting to no-script land, not even being entered into the event queue. This means it will not be triggered after teleporting to a region where scripts are allowed, only the event for that teleport will be triggered.
(As of Second Life 1.16.0 (5) this is not accurate. Teleporting into no-script land will cause the event to trigger once you move onto script-enabled land, as though you had just teleported.)


Aside from the above, the changed() event is also not triggered:

This script uses the changed event with a few other functions to see which notecard was updated, added, or deleted
//written by Ruthven Willenov, added to lslwiki 9/23/2009
list notes;
list ids;
integer note = INVENTORY_NOTECARD;

default
{
    state_entry()
    {
        integer tot = llGetInventoryNumber(note);
        integer i = 0;
        for(i;i < tot;++i)
            {
                string name = llGetInventoryName(note,i);
                key id = llGetInventoryKey(name);
                integer index = llListFindList((list)name,notes);
                if(index = -1 )
                {
                    notes += name;
                    ids += id;
                    llOwnerSay("Added notecard named: " + name);
                }
            }
        }
    changed(integer change)
    {
        if(change & CHANGED_INVENTORY)
        {
            integer tot = llGetInventoryNumber(note);
            integer i = 0;
            for(i;i < tot;++i)
            {
                string name = llGetInventoryName(note,i);
                key id = llGetInventoryKey(name);
                integer index = llListFindList(notes,(list)name);
                if(index == -1 )
                {
                    notes += name;
                    ids += id;
                    llOwnerSay("Added notecard named: " + name);
                }
                else
                if(index >= 0)
                {
                    if(llList2Key(ids,index) != id)
                    {
                        ids = llDeleteSubList(ids,index,index);
                        ids = llListInsertList(ids,(list)id,index);
                        llOwnerSay(name + " was updated");
                    }
                }
            }
            integer len = llGetListLength(notes)-1;
            for(len; len >= 0; --len)
            {
                string name = llList2String(notes,len);
                integer type = llGetInventoryType(name);
                if(type == -1)
                {
                    llOwnerSay(name + " was removed.");
                    notes = llDeleteSubList(notes,len,len);
                    ids = llDeleteSubList(ids,len,len);
                }
            }                
        }
    }
                        
}

Q & A

Q: How do I find out when my object has changed position or rotation?
A: You can't, not by using changed(). The moving_start() and moving_end() event handlers are triggered when the object is moved. To find out when the object is rotated, your best option is to use a timer. (Unless, of course, your object is an attachment, in which case, it will never merely rotate, but will change position constantly, triggering moving_start() and moving_end().)

Q: Regarding bitwise operations: it says above that scale and textures "have been seen" changing at the same time. Does that mean that both CHANGED_TEXTURE and CHANGED_SCALE will always be triggered while scaling a texture with an object?
A: Not necessarily, it just means that they occasionally will be triggered together. You can't predict when this will happen, or even if it will. Make your code able to deal with all possibilities. Assumptions will often produce code that fails, with little indication as to why. As it says above, always write "if (change & CHANGED_LINK)" rather than "if (change == CHANGED_LINK)" so that the contents of your event will be triggered in all cases.

Q: Is there a way to detect when a user buys an object?
A: Yes. Specifying CHANGED_OWNER for change will let you filter the results of changed(). See the details section for specifics.
To detect when a user pays an object, you want the money() event handler.

Q: Is there a way to be notified via an event when a script is added or removed from the object's inventory?
A: No. Your only option is to use a timer to regularly compare the current inventory to a list of preexisting scripts.
A: "The above answer is wrong. Use CHANGED_INVENTORY to compare the current inventory to a list of preexisting scripts, not a timer."
A: "Both answers are correct. You can detect when something gets added with a changed event, but NOT when it gets removed. It needs a timer to detect removals."

Q: Can I use the detection functions (llDetected*) with changed()?
A: No, they only work with touches, collisons and sensors.

Q: Can I find out who (or what) caused the object to change?
A: No.
A: "^^ The above answer is not strictly true as one can compare parameters/states/keys/features of an object before and after the changed event to determine what caused the change. For example to find out what changed the inventory of a prim, first on initialization(state_entry) get the UUID keys of the existing contents using llGetInventoryKey() and store to a variable. When an item is edited and saved it is assigned a new key and the changed event occurs. Compare the new key of the item using llGetInventoryKey() to the previously stored key. If the key's match the item is unchanged. If the keys do not match we know what item changed the prim's inventory."
A: "For CHANGED_OWNER compare new owner key to previous owner key, for CHANGED_SCALE compare the previous scale to the new scale, etc."
A: "One can also determine what event triggered the change event by a debug llSay/llOwnerSay message in the event. Example, a touch causes a scale change."





Events | Detection
Comments [Hide comments/form]
Mind putting that little CHANGED_SCALE bug in the KnownBugs wikiPage?
-- ChristopherOmega (2004-02-17 20:38:21)
Why do we have the values? Because as they apparently are, the values make it clear that one can perform bitwise ops on the values to query multiple changed flags from the changed_flag integer value.
-- ChromalBrodsky (2004-03-24 12:13:19)
And also, why not? ~_^
-- GuzarFonzarelli (2004-03-25 17:01:40)
Protecting people from being clever :)
-- EzharFairlight (2004-03-25 17:54:40)
<-- hasnt used llSetPrimativeParams

You cant administer two simultanious changes STILL?? :-O
-- ChristopherOmega (2004-04-24 22:43:52)
CHANGED_INVENTORY is either buggy or it is documented wrong. I get that as a change when an object is added, renamed, or deleted from the inventory. For notecards, if it is modifed and saved, I get a change. But for scripts, I do not get it for added scripts (or new scripts), or when a script is modified, saved, or reset.
-- ZenoConcord (2005-07-05 20:18:10)
I bugreported that long ago, but it still hasn't been fixed, unfortunately :(
Your best bet would be to use a (ugh) timer.
-- ChristopherOmega (2005-07-14 20:01:23)
Do any of the detection functions work for changed? I tried llDetectedLink() and it doesn't seem to work.
-- ReadyJack (2005-07-16 01:18:42)
Nope, detection functions only work with touch, sensor and collision, also unfortunately.
I made a feature suggestion a *long* time ago asking for the addition of the information about who changed the object, but it went unanswered.
-- ChristopherOmega (2005-07-17 01:44:06)
Reworded the Q&A section to read more formally, and corrected a long-standing bug in the table formatting due to a lack of 'breaking' the bullet-list links to properly terminate and reinitiate them.
-- WolfWings (2005-09-29 01:28:46)
A delay on llUnSit() working "better" is highly debatable. I've noticed that some bugs regarding invisible avatars via an unsit teleport across a great distance. This can be cleared up without the delay. The avatar appears for a split second and then vanishes upon unsitting. This is because the object with the teleport is no longer being seen by the client, so when the teleporting avatar appears, the object they're sitting on isn't rezed. This results in the avatar not being rendered as well.
-- LuccaKitty (2006-05-18 00:53:11)
Is there a way to tell when an object is selected?
-- EepQuirk (2006-06-18 02:52:54)
No, there is currently no way to know if an object is selected. Ive submitted a feature proposal for it though.
-- ChristopherOmega (2006-06-18 17:37:04)
Someone posted that changed() will not be triggered "if the script is in a childprim of a linked set. It must be in the rootprim." This is incorrect, as far as I can tell. Does anyone have anything to add to that?
-- CatherineOmega (2006-06-19 01:00:32)
A script looking for changes in inventory will only trigger the changed() event within the prim it resides. It does not need to be in the rootprim. My vendor system uses a couple of different notecards in different prims with scripts looking for changing inventory in each. They do not interfere with each other, and only one of them is in the rootprim.
-- BurnmanBedlam (2006-06-19 06:50:25)
CHANGED_TELEPORT isn't triggered in a child prim even when it's triggered in an indentical script in the root prim as of 16 Aug 06 (1.11.3)
-- EloisePasteur (2006-08-16 05:11:51)
As of 1.13.1, I seem to have an issue where if I even open up a notecard in a prim's inventory to edit it, the changed() event is triggered with CHANGED_INVENTORY. Anyone else having this issue?
-- StryfeLowell (2006-12-19 10:08:33)
As of 1.13.1 (5), and possibly before (though i haven't noticed before), CHANGED_INVENTORY is triggered when a notecard in an object is closed, even if it hasn't changed. This is probably a bug, and has been reported.
-- GottaLoveForcedCaps (2006-12-26 06:27:28)
Masses of comment spam here...
-- cpc1-midd9-0-0-cust684.midd.cable.ntl.com (2007-08-28 02:53:38)
How do we get rid of all this stupid spam on this page?
-- 72-12-23-254.wan.networktel.net (2007-09-10 17:57:27)
My understanding is that, in case an avatar buys the content of an object by 0L, the event CHANGED_OWNER is issued. But how do I know who purchased the object's content?
-- blueice1n1.de.ibm.com (2007-10-26 01:03:44)
Attach a comment to this page: