~2.5 years back you could not pass a script of the same name to another prim via llGiveInventory... it would silently fail... in fact it silently failed for pretty much any identically named item...
The Present:
fast forward to sometime since then, and you now can, and the duplicate script gains a number after it identically to the behavior of dragging a duplicate script from inventory to a prim... no big deal you say; those scripts won't be running so what's the use....
The Trick:
you CAN take one of these newly numbered scripts and send it back, active, if you use remote load script pin.... which will replace a script of the same name... but since it's been newly numbered, it has a different name. if said script is used to store avatar permissions, like PERMISSION_TRIGGER_ANIMATION, you can now dynamically add those permission scripts without running out of room, running a bunch of idle scripts, preloading a ton of non-running copies, or usinging complicated systems to switch said preloads on and off, all while avoiding repetitive permissions dialogs on things like dance balls and huggers...
The Example:
two prim object, 3 scripts, A, B, C
Scripts B and C go in the root.
Script A goes in the child, along with a non running copy of B
(go ahead and name them this for the example to work
Script A
CODE
default{
changed( integer vBitChg ){
if (CHANGED_INVENTORY & vBitChg){
llRemoteLoadScriptPin( llGetLinkKey( 1 ),
llGetInventoryName( INVENTORY_SCRIPT, llGetInventoryNumber( INVENTORY_SCRIPT ) - 1 ),
42,
1,
42 );
}
}
}
Script B
CODE
key gKeyAva;
string gStrCmd;
default{
link_message( integer vIntLnk, integer vIntNum, string vStrCmd, key vKeyAva ){
if (vIntNum){
llGiveInventory( llGetLinkKey( 2 ), "v7-D Permission" );
gKeyAva = vKeyAva;
gStrCmd = vStrCmd;
state sAvatarStored;
}
}
}
state sAvatarStored{
state_entry(){
llRequestPermissions( gKeyAva, PERMISSION_TRIGGER_ANIMATION );
}
run_time_permissions( integer vBitPrm ){
if (PERMISSION_TRIGGER_ANIMATION & vBitPrm){
llStartAnimation( gStrCmd );
llSetTimerEvent( 3600.0 );
}else{
llRemoveInventory( llGetScriptName() );
}
}
link_message( integer vIntLnk, integer vIntNum, string vStrCmd, key vKeyAva ){
if (gKeyAva == vKeyAva){
llSetTimerEvent( 3600.0 );
if ("STOP" == vStrCmd){
llStopAnimation( gStrCmd );
}else{
llStartAnimation( (gStrCmd = vStrCmd) );
}
}
}
timer(){
llStopAnimation( gStrCmd );
llRemoveInventory( llGetScriptName() );
}
}
Script C
CODE
list gLstKwn;
default{
state_entry(){
llSetRemoteScriptAccessPin( 42 );
}
touch_start( integer total_number ){
key vKeyAv = llDetectedKey( 0 );
integer vBooNew = !~llListFindList( gLstKwn, (list)vKeyAv );
if (vBooNew){
gLstKwn += (list)vKeyAv;
}
llMessageLinked( LINK_THIS, vBooNew, "dance1", vKeyAv );
}
}
I've already included the start of some safety protocols in there, timeouts and permission checks to remove denied or stale permissions (needs code to update the controller) the start of reset protection (perms script needs to check start parameter), but this should give you the general idea...
now someone tap Very Keynes and tell him his database script(s) can now dynamically load memory cell scripts