Perhaps you, like me, find yourself
copying the contents of one object into another, for example to move
a whole bunch of animations from one piece of furniture into a new
one. Out of habit, I've always done this by first copying everything
into my own Inventory, then back out to the other object. This is
really slow and prone to failure. Some third party viewers have a way
to make it a little more reliable, but it's still pretty painful.
Thanks to particularly sluggish
Inventory services I recently realized that this was a silly extra
step: All I really need to do is copy the contents directly, object
to object. So here's a script that does that (read the comments for
some caveats and options about how it works):
/*
Simple little script to copy the
contents of this prim to another, identified by key in textbox
To get the key to put in that
textbox, can use Firestorm's "Copy Keys" button in the
Build Tool editor or drop this trivial script into
the target object:
default { state_entry() {
llOwnerSay((string)llGetKey()); } }
Unfortunately (and weirdly) I don't
know a way for a script to get the permissions on a rezzed object, so this will try to copy to
anything the toucher owns, which won't work for no-mod targets. This expects both the sending and
recipient objects to be owned by the toucher.
Some special cases might make sense
with other owners, but lots of ways for that to cause trouble, too. Can theoretically use something
like this to give contents to an avatar
but as written it would wait 2
seconds between items. Some TPVs have built-in means of doing this
reliably.
Could use llGiveInventoryList() to
make it faster, but that can't work at all for no-copy,
which would mean a hybrid approach,
much like product unpacking scripts.
*/
integer COPY_SCRIPTS = FALSE;
// Scripts would arrive confusingly NOT
running (use TRUE to copy them anyway, including THIS script,
// but then will need to either
recompile them or take target object into inventory and re-rez it.)
integer MOVE_NO_COPY_CONTENTS = FALSE;
// It could damage the sender; use TRUE
to do it anyway, but that won't work if copying to an attachment
integer listenHandle;
default
{
touch_start(integer num_detected)
{
key toucher = llDetectedKey(0);
if (llGetOwner() != toucher)
{
llRegionSayTo(toucher, 0,
"You need to own this object to copy its contents");
return;
}
llListenRemove(listenHandle);
integer chan = -1000000000 -
(integer)llFrand(1000000000);
llListen(chan, "",
toucher, "");
llTextBox(toucher, "Key
(UUID) of recipient object?", chan);
}
listen(integer channel, string
name, key id, string text)
{
key target = (key)text;
if (NULL_KEY == target)
llRegionSayTo(id, 0,
"Sorry, that's not a valid key");
else
if (id !=
llGetOwnerKey(target))
llRegionSayTo(id, 0,
"Sorry, you don't own that object");
else
{
integer inv =
llGetInventoryNumber(INVENTORY_ALL);
while (--inv >= 0)
{
string invName =
llGetInventoryName(INVENTORY_ALL, inv);
if (COPY_SCRIPTS ||
(INVENTORY_SCRIPT != llGetInventoryType(invName)))
{
if (! (PERM_COPY &
llGetInventoryPermMask(invName, MASK_OWNER)))
if
(MOVE_NO_COPY_CONTENTS)
llGiveInventory(target, invName);
else
llRegionSayTo(id, 0, "Skipping no-copy contents: "+invName);
else
llGiveInventory(target, invName);
}
}
llRegionSayTo(id, 0,
llGetScriptName()+": Done");
}
}
}
Reporter Qie Niangao
200302
No comments:
Post a Comment