Difference between revisions of "User:Susicat Oh"

From Second Life Wiki
Jump to navigation Jump to search
(Simple plain English explanations of LSL commands and functions)
 
m
Line 1: Line 1:
Background:
Background:


Name Susicat Oh
Name: {{User|Susicat Oh}}


Born June 07
Born: June 07


Time in SL  5 years in 2012
Time in SL  5 years in 2012
Line 11: Line 11:
Aim of this page is to provide simple plain English explanations of LSL commands and functions with examples where I can.
Aim of this page is to provide simple plain English explanations of LSL commands and functions with examples where I can.


Trip ups, idocyncracies and folbles.
Trip ups, idiosyncrasies and foibles.




An undefined key may not be held as 00000000.. undefined keys as varialbes are held as empty NOT 000000...  as such if you need to test for NULL_KEY be sure to set the variable to NULL_KEY as required.   
An undefined key may not be held as 00000000.. undefined keys as variables are held as empty NOT 000000...  as such if you need to test for NULL_KEY be sure to set the variable to [[NULL_KEY]] as required.   






llSetPrimitiveParams([PRIM_POSITION,dest]);
<lsl>llSetPrimitiveParams([PRIM_POSITION,dest]);</lsl>


This needs to be in the root prim or will fail.
This needs to be in the root prim or will fail.
Line 24: Line 24:




sensor returns the 16 closest detedcted "items" in order of closest to farthest they are  
[[sensor]] returns the 16 closest detected "items" in order of closest to farthest they are  
numbered "sensor( integer num)as 1 to 16. this function will NEVER return a zero!!  of you  
numbered <code>sensor( integer num)</code> as 0 to 15. this function will NEVER return a zero!!  if you  
need to test for zero use no_sensor as a zero scan will not trigger a sensor event..
need to test for zero use [[no_sensor]] as a zero scan will not trigger a sensor event..


Also note llSensorRemove() not only  shuts down the active sensor set up with llSensorRepeat BUT will ALSO kill the sensor found data.  
Also note [[llSensorRemove]]() not only  shuts down the active sensor set up with [[llSensorRepeat]] BUT will ALSO kill the sensor found data.  


as such
as such


sensor(integer num_detected)
<lsl>sensor(integer num_detected)
{
{
llSensorRemove();
llSensorRemove();
 
}</lsl>


is futile as  the senor data will get wiped.
is futile as  the senor data will get wiped.
 
<lsl>sensor(integer num_detected)
sensor(integer num_detected)
{
{
code  funtions what ever your  trying to do  etc.
//code  functions what ever your  trying to do  etc.
....
//....
...
//...
followed by
//followed by
llSensorRemove();
llSensorRemove();
}
}</lsl>
 
will work fine.
will work fine.


Also note  if your using a single sweep one-off type scan look at llSensor. Using llSensorReapeat() then shutting it off immediately is a waste of byte code.     
Also note  if your using a single sweep one-off type scan look at [[llSensor]]. Using [[llSensorRepeat]]() then shutting it off immediately is a waste of byte code.     




llList2Vector and llList2Rotation do work as documented (or have been fixed) the poblem with them stems from the fact that
[[llList2Vector]] and [[llList2Rot]] do work as documented (or have been fixed) the problem with them stems from the fact that
sometimes numerical data passed  between scripts is usually passed as strings the  recieving script accepts the string,   
sometimes numerical data passed  between scripts is usually passed as strings the  receiving script accepts the string,   
you then add it to a list. The data then sits in the list as a STRING!!  not a numeric value. if you  llDumpList2string
you then add it to a list. The data then sits in the list as a STRING!!  not a numeric value. if you  llDumpList2string
you will see  something  with looks like a numerical value, feels like a numerical value BUT its a string!! You need to be  
you will see  something  with looks like a numerical value, feels like a numerical value BUT its a string!! You need to be  
on your toes all the time when transfering data types and remember to typcast correctly.       
on your toes all the time when transferring data types and remember to typecast correctly.       






llSetpos  does not work in attached prims Linden are aware of this and are fixing it  
[[llSetPos]] does not work in attached prims Linden are aware of this and are fixing it  




llKey2Name avatar MUST be on line AND in the sim or a child avatar of the sim, or a NULL_KEY is returned.
[[llKey2Name]] avatar MUST be online AND in the sim or a child avatar of the sim, or a [[NULL_KEY]] is returned.
use llRequestAgentData and dataserver to get round this.
use [[llRequestAgentData]] and [[dataserver]] to get round this.


* child avatar is diffined as avatar on a neigboring sim which can be seen from the sim the script is in (less than 35M from sim boundary).
* child avatar is defined as avatar on a neighboring sim which can be seen from the sim the script is in (less than 35M from sim boundary).


llkey2name is now only legacy..  as of  Dec 2010.  Use llGetUsername( key id ) instead..  
[[llKey2Name]] is now only legacy (as of  Dec 2010).  Use <code>[[llGetUsername]]( key id )</code> instead..  


Also be aware of llGetDisplayName( key id ); you are reminded that displaynames are not unique and easily changed, using them in ANY security script is a really bad plan!! Use llGetusername(id) or do it with avatar keys!!
Also be aware of <code>[[llGetDisplayName]]( key id );</code> you are reminded that displaynames are not unique and easily changed, using them in ANY security script is a really bad plan!! Use <code>[[llGetUsername]](id)</code> or do it with avatar keys!!


I would suggest using llRequestDisplayName(id) it will raise a dataserver event but gets round the issue of avatar not in sim.
I would suggest using <code>[[llRequestDisplayName]](id)</code> it will raise a [[dataserver]] event but gets round the issue of avatar not in sim.


Newer people in SL will have the second name "Resident"    
Newer people in SL will have the second name "Resident"




This one does actually work as documented BUT you need to be clear what it returns.
This one does actually work as documented BUT you need to be clear what it returns.


key llGetCreator();  returns the creator of the prim! NOT the script!
<lsl>key llGetCreator();  //returns the creator of the prim! NOT the script!
key llGetInventoryCreator(string <inventory name>); returns the creator of inventory item ie script author or texture creator etc..  
key llGetInventoryCreator(string <inventory name>); //returns the creator of inventory item ie script author or texture creator etc.. </lsl>




change & CHANGED_INVENTORY does not trigger   for llAllowinventorydrop  or llRemoveinventory documented else where on wiki
<code>change & [[CHANGED_INVENTORY]]</code> does not trigger for [[llAllowInventoryDrop]] or [[llRemoveInventory]] documented else where on wiki


changed_Inventory will work when the prim owner edits the prim manually (adding a texture  editing a notecard)
<code>[[CHANGED_INVENTORY]]</code> will work when the prim owner edits the prim manually (adding a texture  editing a notecard)


      
      
Use CHANGED_ALLOWED_DROP instead  which will trigger when inventory is added  via llallowinventorydrop
Use [[CHANGED_ALLOWED_DROP]] instead  which will trigger when inventory is added  via [[llAllowInventoryDrop]]


the llRemoveinventory issue has been acknowledged by Linden who are "working on it"  
the [[llRemoveInventory]] issue has been acknowledged by Linden who are "working on it"  


On the  subject of llAllowInventoryDrop it allows  any one to add anything to the  prim.
On the  subject of [[llAllowInventoryDrop]] it allows  any one to add anything to the  prim.
Its up to you  to figure out  the validity of  who dropped what.
Its up to you  to figure out  the validity of  who dropped what.
    
    
Line 99: Line 97:




DATA_ONLINE returns binary integer TRUE/FALSE  BUT!!  the dataserver event can only accept strings
[[DATA_ONLINE]] returns binary integer TRUE/FALSE  BUT!!  the [[dataserver]] event can only accept strings
as such  dataserver(key queryid, string data)  data will be a "1" (online) or "0"(offline) as a string. attepting to use dataserver(key queryid, integer data)  will force a syntax error when you try to complie.  
as such  dataserver(key queryid, string data)  data will be a "1" (online) or "0"(offline) as a string. attempting to use dataserver(key queryid, integer data)  will force a syntax error when you try to compile.  




Adding a semi colon to if statements   as if( a ==B);   will cause the test to return TRUE everytime handy for debugging but may have you scratching your head for hours.
Adding a semi colon to <code>[[if]]</code> statements as <code>[[if]]( a == B);</code> will cause the test to return [[TRUE]] every time handy for debugging but may have you scratching your head for hours. This is because the semi colon satisfies the condition's following statement requirement, so any following statements are treated as if they are not associated with the conditional.


on the subject of  ; in the wrong place...
on the subject of  ; in the wrong place...


while (a < b);
<lsl>while (a < b);</lsl>


with a semi-colon will stall the script. It will compile it will not error the script will just sulk!
with a semi-colon will stall the script. It will compile it will not error the script will just sulk!
    
    


llGiveMoney(key,amount); key MUST be an avatar and  amount MUST be an integer greater than zero  passing a float or a zero will error.  
<code>[[llGiveMoney]](key,amount);</code> key MUST be an avatar and  amount MUST be an integer greater than zero  passing a float or a zero will error.  


side note for  give money profit split
side note for  give money profit split
Line 118: Line 116:
integer to float  and division  
integer to float  and division  


integer a = whatever;
<lsl>integer a = whatever;
integer b = whatever;
integer b = whatever;
float c = a/b;
float c = a/b;</lsl>


May yield c = zero  due to internal integer rounding in LSL which will  cause llGivemoney to throw invalid amount error.
May yield c = zero  due to internal integer rounding in LSL which will  cause [[llGiveMoney]] to throw invalid amount error.


use
use
float a = money_amount;
<lsl>float a = money_amount;
float b = percent_split;
float b = percent_split;
integer given = llRound((money_amount/100) * percent_split);  
integer given = llRound((money_amount/100) * percent_split);  
llGiveMoney(id,given);
llGiveMoney(id,given);</lsl>
 
OR
 
<lsl>integer a = whatever;
integer b = whatever;
float c = a/(float)b;</lsl>


I have tripped up on this more than once!
I have tripped up on this more than once!
Line 134: Line 138:




List length limit at compile is 72 elements BUT  once compiled  list can be added  
List length limit at compile is 72 elements BUT  once compiled  list can be added  
list huge = list1 + list2;  will work fine  
list huge = list1 + list2;  will work fine  


Line 140: Line 144:




llDialog
[[llDialog]]
The problem is that the client font is proportionally spaced not fixed with font soo this is best guess guide.  
The problem is that the client font is proportionally spaced not fixed with font soo this is best guess guide.  


Line 153: Line 157:
cannot exceed 24 characters
cannot exceed 24 characters
Long button labels will be truncated in the display to circa 12 characters (remember its proportional spacing) in practice aim for max 10 chrs.  
Long button labels will be truncated in the display to circa 12 characters (remember its proportional spacing) in practice aim for max 10 chrs.  
Similar button labels which get truncated  will look the same in the display aviod "sitting here pose 1","sitting here pose 2"  as truncation whill show them as the same, the script knows they are different and will work correctly  but the human user will not see a difference.  
Similar button labels which get truncated  will look the same in the display avoid "sitting here pose 1","sitting here pose 2"  as truncation will show them as the same, the script knows they are different and will work correctly  but the human user will not see a difference.  




llMessageLinked
[[llMessageLinked]]
This will appear to stall or not work  if messages are sent to quickly you need to allow the processing time of the recieving script.
This will appear to stall or not work  if messages are sent to quickly you need to allow the processing time of the receiving script.
slow things down with llSleep(x) in practice 0.1 is normaly enough.
slow things down with [[llSleep]](x) in practice 0.1 is normally enough.




    
    
llParticleSystem the list option PSYS_SRC_TARGET_KEY,NULL_KEY will compile but crashes the script..  Use PSYS_SRC_TARGET_KEY,(key)"" as a work round.
[[llParticleSystem]] the list option <code>PSYS_SRC_TARGET_KEY, [[NULL_KEY]]</code> will compile but crashes the script..  Use <code>PSYS_SRC_TARGET_KEY,(key)""</code> as a work round. Or <code>PSYS_SRC_TARGET_KEY, (key)[[NULL_KEY]]</code>




money event  is  not capable of  telling if  a "correct amount" was paid  it will return amount and  the payers key but thats it.. its up to you  to test amount
[[money]] event  is  not capable of  telling if  a "correct amount" was paid  it will return amount and  the payers key but thats it.. its up to you  to test amount


if(amount paid  == price)
<lsl>if(amount paid  == price)
{
{
deliver item
deliver item
}
}</lsl>


The money event can be in any prim and will work as "pay this prim" just fine  BUT  llSetPayPrice(integer,[list]);  for  the pay dialog box  MUST be in the root prim. If llSetPayPrice is in a child prim it will fail silently. Its ok to have it in the root as all money events in the object will be updated automatically.
The money event can be in any prim and will work as "pay this prim" just fine  BUT  [[llSetPayPrice]](integer,[list]);  for  the pay dialog box  MUST be in the root prim. If [[llSetPayPrice]] is in a child prim it will fail silently. Its ok to have it in the root as all money events in the object will be updated automatically.


it is NOT possible to pay a worn attachment.  
it is NOT possible to pay a worn attachment.  
Line 182: Line 186:
There is a 64 event limit on any  given state.
There is a 64 event limit on any  given state.
Events are processed on a strict first in first out order  (FIFO)  
Events are processed on a strict first in first out order  (FIFO)  
The only thing that can jump the que is state_entry
The only thing that can jump the queue is state_entry


The event que is 64 events after that events are discarded untill there is free space in the que.
The event queue is 64 events after that events are discarded until there is free space in the queue.
Thats why if you are sending  batches of LinkMessage( some of them get lost or never arrive.
That's why if you are sending  batches of LinkMessage( some of them get lost or never arrive.


Side note:  The word "event" is an LSL keyword and will syntax error if used.   
Side note:  The word "event" is an LSL keyword and will syntax error if used.   
Line 194: Line 198:
HOWEVER  having been given a key there is no way of testing if its an avatar, texture, group, sound,  animation or whatever.  Your expected to know!!
HOWEVER  having been given a key there is no way of testing if its an avatar, texture, group, sound,  animation or whatever.  Your expected to know!!


list tmp = llGetObjectDetails(id,[OBJECT_OWNER]);
<lsl>list tmp = llGetObjectDetails(id,[OBJECT_OWNER]);


if(llList2key(tmp,0) == id)
if(llList2Key(tmp,0) == id)
{
{
key is an avatar;
key is an avatar;
}
}
if(llList2key(tmp,0) == NULL_KEY)
if(llList2Key(tmp,0) == NULL_KEY)
{
{
key is NOT an avatar;
key is NOT an avatar;
}
}
 
</lsl>
thats the best I have for now  
thats the best I have for now  


Line 212: Line 216:
Integer rounding.  
Integer rounding.  


 
When rounding the results of [[llFrand]], you should always use the float->integer typecast.
integer a = llRound(llFrand(4));  returns  values in the range 0 - 4 inc.
<lsl>integer a = (integer)llFrand(4);  //returns  values in the range 0 - 3 inc. odds {0:1/4, 1:1/4, 2:1/4, 3:1/4}
integer a = llFloor(llFrand(4));  0 - 3 inc
integer a = llRound(llFrand(4));  //0 - 4 inc. odds {0:1/8, 1:1/4, 2:1/4, 3:1/4, 4:1/8}
integer a = llCeil(llFrand(4));    1 - 4 inc
integer a = llFloor(llFrand(4));  //0 - 3 inc. odds {0:1/4, 1:1/4, 2:1/4, 3:1/4}
integer a = llCeil(llFrand(4));    //0 - 4 inc. odds {0:tiny, 1:1/4, 2:1/4, 3:1/4, 4:slightly less than 1/4}</lsl>




Line 221: Line 226:
On Rez  reset fails when taken from inventory  for the first time.
On Rez  reset fails when taken from inventory  for the first time.


Never got to the bottom of this as reseting scripts manually in world or shift drag copying clears the fault.
Never got to the bottom of this as resetting scripts manually in world or shift drag copying clears the fault.


Current thinking is that  you use CHANGED_INVENTORY reset and  may be a permission request  like  permission money.
Current thinking is that  you use [[CHANGED_INVENTORY]] reset and  may be a permission request  like  permission money.




What may be happening is you are setting up next owner permissions  which triggers your CHANGED_INVENORY reset  then in your  haste  you take back to inventory without  granting  the money permission.  As a result  the object sits in inventory without money permission being granted and  just hangs in limbo. It has asked for money permisson once and cannot ask again without a reset, the  section of code that does the resetting cannot be executed as permission has not been granted thus preventing the script advancing through to the code to get to the reset routines.
What may be happening is you are setting up next owner permissions  which triggers your [[CHANGED_INVENTORY]] reset  then in your  haste  you take back to inventory without  granting  the money permission.  As a result  the object sits in inventory without money permission being granted and  just hangs in limbo. It has asked for money permisson once and cannot ask again without a reset, the  section of code that does the resetting cannot be executed as permission has not been granted thus preventing the script advancing through to the code to get to the reset routines.


Solutions
Solutions


1/  Add an on-rez  reset to the  same  state (usually  default) as the money request.
# Add an on-rez  reset to the  same  state (usually  default) as the money request.
2/  Always remember to set it up correcly before taking to inventory.
# Always remember to set it up correctly before taking to inventory.
3/  Test rez the item to be sure it  does initalise correctly.
# Test rez the item to be sure it  does initialize correctly.
4/  Slap your self  for being  stupid.
# Slap your self  for being  stupid.
5/  All of the above.
# All of the above.

Revision as of 08:54, 30 April 2012

Background:

Name: Susicat Oh

Born: June 07

Time in SL 5 years in 2012


Aim of this page is to provide simple plain English explanations of LSL commands and functions with examples where I can.

Trip ups, idiosyncrasies and foibles.


An undefined key may not be held as 00000000.. undefined keys as variables are held as empty NOT 000000... as such if you need to test for NULL_KEY be sure to set the variable to NULL_KEY as required.


<lsl>llSetPrimitiveParams([PRIM_POSITION,dest]);</lsl>

This needs to be in the root prim or will fail. In a child prim not only does it fail it can throw "stack heap collision"


sensor returns the 16 closest detected "items" in order of closest to farthest they are numbered sensor( integer num) as 0 to 15. this function will NEVER return a zero!! if you need to test for zero use no_sensor as a zero scan will not trigger a sensor event..

Also note llSensorRemove() not only shuts down the active sensor set up with llSensorRepeat BUT will ALSO kill the sensor found data.

as such

<lsl>sensor(integer num_detected) { llSensorRemove(); }</lsl>

is futile as the senor data will get wiped. <lsl>sensor(integer num_detected) { //code functions what ever your trying to do etc. //.... //... //followed by llSensorRemove(); }</lsl> will work fine.

Also note if your using a single sweep one-off type scan look at llSensor. Using llSensorRepeat() then shutting it off immediately is a waste of byte code.


llList2Vector and llList2Rot do work as documented (or have been fixed) the problem with them stems from the fact that sometimes numerical data passed between scripts is usually passed as strings the receiving script accepts the string, you then add it to a list. The data then sits in the list as a STRING!! not a numeric value. if you llDumpList2string you will see something with looks like a numerical value, feels like a numerical value BUT its a string!! You need to be on your toes all the time when transferring data types and remember to typecast correctly.


llSetPos does not work in attached prims Linden are aware of this and are fixing it


llKey2Name avatar MUST be online AND in the sim or a child avatar of the sim, or a NULL_KEY is returned. use llRequestAgentData and dataserver to get round this.

  • child avatar is defined as avatar on a neighboring sim which can be seen from the sim the script is in (less than 35M from sim boundary).

llKey2Name is now only legacy (as of Dec 2010). Use llGetUsername( key id ) instead..

Also be aware of llGetDisplayName( key id ); you are reminded that displaynames are not unique and easily changed, using them in ANY security script is a really bad plan!! Use llGetUsername(id) or do it with avatar keys!!

I would suggest using llRequestDisplayName(id) it will raise a dataserver event but gets round the issue of avatar not in sim.

Newer people in SL will have the second name "Resident"


This one does actually work as documented BUT you need to be clear what it returns.

<lsl>key llGetCreator(); //returns the creator of the prim! NOT the script! key llGetInventoryCreator(string <inventory name>); //returns the creator of inventory item ie script author or texture creator etc.. </lsl>


change & CHANGED_INVENTORY does not trigger for llAllowInventoryDrop or llRemoveInventory documented else where on wiki

CHANGED_INVENTORY will work when the prim owner edits the prim manually (adding a texture editing a notecard)


Use CHANGED_ALLOWED_DROP instead which will trigger when inventory is added via llAllowInventoryDrop

the llRemoveInventory issue has been acknowledged by Linden who are "working on it"

On the subject of llAllowInventoryDrop it allows any one to add anything to the prim. Its up to you to figure out the validity of who dropped what.



DATA_ONLINE returns binary integer TRUE/FALSE BUT!! the dataserver event can only accept strings as such dataserver(key queryid, string data) data will be a "1" (online) or "0"(offline) as a string. attempting to use dataserver(key queryid, integer data) will force a syntax error when you try to compile.


Adding a semi colon to if statements as if( a == B); will cause the test to return TRUE every time handy for debugging but may have you scratching your head for hours. This is because the semi colon satisfies the condition's following statement requirement, so any following statements are treated as if they are not associated with the conditional.

on the subject of  ; in the wrong place...

<lsl>while (a < b);</lsl>

with a semi-colon will stall the script. It will compile it will not error the script will just sulk!


llGiveMoney(key,amount); key MUST be an avatar and amount MUST be an integer greater than zero passing a float or a zero will error.

side note for give money profit split

integer to float and division

<lsl>integer a = whatever; integer b = whatever; float c = a/b;</lsl>

May yield c = zero due to internal integer rounding in LSL which will cause llGiveMoney to throw invalid amount error.

use <lsl>float a = money_amount; float b = percent_split; integer given = llRound((money_amount/100) * percent_split); llGiveMoney(id,given);</lsl>

OR

<lsl>integer a = whatever; integer b = whatever; float c = a/(float)b;</lsl>

I have tripped up on this more than once!


List length limit at compile is 72 elements BUT once compiled list can be added list huge = list1 + list2; will work fine

The only real limit is script memory.


llDialog The problem is that the client font is proportionally spaced not fixed with font soo this is best guess guide.

Question text is circa 35 characters per line Its ok to use \n and \t for new line and tab At more than 8 lines you get a scroll bar. Whatever you do question text MUST be greater than none and LESS than 512 characters.

Buttons Labels MUST be strings Cannot be empty or NULL sting (spaces are permitted) cannot exceed 24 characters Long button labels will be truncated in the display to circa 12 characters (remember its proportional spacing) in practice aim for max 10 chrs. Similar button labels which get truncated will look the same in the display avoid "sitting here pose 1","sitting here pose 2" as truncation will show them as the same, the script knows they are different and will work correctly but the human user will not see a difference.


llMessageLinked This will appear to stall or not work if messages are sent to quickly you need to allow the processing time of the receiving script. slow things down with llSleep(x) in practice 0.1 is normally enough.


llParticleSystem the list option PSYS_SRC_TARGET_KEY, NULL_KEY will compile but crashes the script.. Use PSYS_SRC_TARGET_KEY,(key)"" as a work round. Or PSYS_SRC_TARGET_KEY, (key)NULL_KEY


money event is not capable of telling if a "correct amount" was paid it will return amount and the payers key but thats it.. its up to you to test amount

<lsl>if(amount paid == price) { deliver item }</lsl>

The money event can be in any prim and will work as "pay this prim" just fine BUT llSetPayPrice(integer,[list]); for the pay dialog box MUST be in the root prim. If llSetPayPrice is in a child prim it will fail silently. Its ok to have it in the root as all money events in the object will be updated automatically.

it is NOT possible to pay a worn attachment.


Events

There is a 64 event limit on any given state. Events are processed on a strict first in first out order (FIFO) The only thing that can jump the queue is state_entry

The event queue is 64 events after that events are discarded until there is free space in the queue. That's why if you are sending batches of LinkMessage( some of them get lost or never arrive.

Side note: The word "event" is an LSL keyword and will syntax error if used.


keys as 36 character UUIDs can be type cast to string and back fluidly just be aware of type casting when performing key functions.

HOWEVER having been given a key there is no way of testing if its an avatar, texture, group, sound, animation or whatever. Your expected to know!!

<lsl>list tmp = llGetObjectDetails(id,[OBJECT_OWNER]);

if(llList2Key(tmp,0) == id) { key is an avatar; } if(llList2Key(tmp,0) == NULL_KEY) { key is NOT an avatar; } </lsl> thats the best I have for now



Integer rounding.

When rounding the results of llFrand, you should always use the float->integer typecast. <lsl>integer a = (integer)llFrand(4); //returns values in the range 0 - 3 inc. odds {0:1/4, 1:1/4, 2:1/4, 3:1/4} integer a = llRound(llFrand(4)); //0 - 4 inc. odds {0:1/8, 1:1/4, 2:1/4, 3:1/4, 4:1/8} integer a = llFloor(llFrand(4)); //0 - 3 inc. odds {0:1/4, 1:1/4, 2:1/4, 3:1/4} integer a = llCeil(llFrand(4)); //0 - 4 inc. odds {0:tiny, 1:1/4, 2:1/4, 3:1/4, 4:slightly less than 1/4}</lsl>


On Rez reset fails when taken from inventory for the first time.

Never got to the bottom of this as resetting scripts manually in world or shift drag copying clears the fault.

Current thinking is that you use CHANGED_INVENTORY reset and may be a permission request like permission money.


What may be happening is you are setting up next owner permissions which triggers your CHANGED_INVENTORY reset then in your haste you take back to inventory without granting the money permission. As a result the object sits in inventory without money permission being granted and just hangs in limbo. It has asked for money permisson once and cannot ask again without a reset, the section of code that does the resetting cannot be executed as permission has not been granted thus preventing the script advancing through to the code to get to the reset routines.

Solutions

  1. Add an on-rez reset to the same state (usually default) as the money request.
  2. Always remember to set it up correctly before taking to inventory.
  3. Test rez the item to be sure it does initialize correctly.
  4. Slap your self for being stupid.
  5. All of the above.