https://wiki.secondlife.com/w/api.php?action=feedcontributions&user=Toady+Nakamura&feedformat=atomSecond Life Wiki - User contributions [en]2024-03-29T05:27:23ZUser contributionsMediaWiki 1.36.1https://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1210379User:Toady Nakamura2021-12-04T02:34:41Z<p>Toady Nakamura: add one</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Curates basic SL Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
||[[User:Toady Nakamura/Avatar_Key_and_Name|Avatar Key and Name]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Ask for and receive Avatar name and key data.<br />
|-<br />
||[[User:Toady Nakamura/Owner_Only|Owner (& friends) Only]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Responds to the touch of owner, owner & friends, or not at all!<br />
|-<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Ribbon Particle|Rainbow Ribbon Tail to Wear]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Rainbow particle tail to wear.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, object says new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
<br />
|-{{Hl2}}<br />
! '''Chatbots'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/ELIZA_chatbot|ELIZA_chatbot]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Eliza is a legendary 1966 computer program written by Joseph Weizenbaum. Here it is for LSL.<br />
|-<br />
||[[User:Toady Nakamura/LindenAIML|LindenAIML]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language).<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Avatar_Key_and_Name&diff=1210378User:Toady Nakamura/Avatar Key and Name2021-12-04T02:31:24Z<p>Toady Nakamura: create find avi key & name based on student request</p>
<hr />
<div>==Find avatar name and key==<br />
How to <br />
- ask for and use string data<br />
- ask for and use key data<br />
- convert key data to string data for chat output<br />
<br />
<br />
<source lang="lsl2"><br />
string Gname; <br />
key Gkeey;<br />
<br />
default<br />
{<br />
touch_start(integer total_number)<br />
{<br />
Gname = llDetectedName(0);<br />
Gkeey = llDetectedKey(0);<br />
<br />
llRegionSayTo(Gkeey, 0, Gname + ", your UUID is: " + (string)Gkeey );<br />
}<br />
}<br />
<br />
</source><br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=LlDetectedType&diff=1210305LlDetectedType2021-10-05T00:57:35Z<p>Toady Nakamura: dead link removal</p>
<hr />
<div>{{LSL_Function<br />
|inject-2={{LSL_Function/detected|number|type|error={{HoverText|zero|0}}}}<br />
|func_id=34|func_sleep=0.0|func_energy=10.0<br />
|sort=DetectedType|func=llDetectedType<br />
|return_type=integer<br />
|p1_type=integer|p1_name=number<br />
|func_footnote=Returns {{HoverText|zero|0}} if {{LSLP|number}} is not valid sensed object or avatar.<br />
|func_desc<br />
|return_text=mask that is the types of detected object or avatar.<br />
|spec<br />
|caveats<br />
|constants={{LSL Constants Sensor}}<br />
|examples=<br />
<source lang="lsl2"><br />
//--// Type & name of collision source //--//<br />
<br />
default{<br />
collision_start( integer vIntCollided ){<br />
integer vBitType;<br />
string vStrType;<br />
do<br />
{<br />
vBitType = llDetectedType( --vIntCollided );<br />
if (vBitType & AGENT_BY_LEGACY_NAME)<br />
vStrType = "avatar";<br />
else<br />
vStrType = "object";<br />
llOwnerSay( "An " + vStrType + " named '" + llDetectedName( vIntCollided ) + "' collided with me" );<br />
}<br />
while (vIntCollided);<br />
}<br />
}<br />
</source><br />
|helpers<br />
|also_functions<br />
|also_events<br />
|also_articles=<br />
|notes<br />
|permission<br />
|cat1<br />
|cat2<br />
|cat3<br />
|cat4<br />
}}</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=LlGetObjectDetails&diff=1210078LlGetObjectDetails2021-06-01T21:41:30Z<p>Toady Nakamura: There were typos that prevented the first example script from working in SL, I fixed the page from a working copy</p>
<hr />
<div>{{LSL_Function<br />
|inject-2=<br />
{{LSL_Function/limits}}{{LSL_Function/uuid|id|sim=*}}<br />
{{Issues/SCR-87}}{{Issues/SVC-7592}}<br />
|func_id=332|func_sleep=0.0|func_energy=10.0<br />
|func=llGetObjectDetails<br />
|p1_type=key|p1_name=id|p1_desc=&#32;or adjacent regions[[#id_Parameter|*]]<br />
|p2_type=list|p2_name=params|p2_desc=OBJECT_* flags<br />
|return_type=list|return_text=of the details for {{LSLP|id}}, specifically those requested in {{LSLP|params}}. <br />
|func_footnote=An empty list if {{LSLP|id}} is not found.{{PBR}}<br />
{{LSL Const|OBJECT_UNKNOWN_DETAIL|integer|-1|c=}} is returned when passed an invalid integer parameter.<br />
|spec=<div style="padding: 1px; float: left;">[[Image:LlGetObjectdetails-avatar-range.png|thumb=LlGetObjectdetails-avatar-range-thumb.jpg|none|250px|Avatar detection range for SL Server 1.34]]</div><br />
<h5 style="margin:0;">{{LSLP|id}} Parameter</h5><br />
{{LSLP|id}} holds the [[UUID]] of the avatar or prim this function is going to get the details of.<br />
<br />
If {{LSLP|id}} is not found in the region, adjacent regions are searched for avatars which match {{LSLP|id}}. An avatar is only considered to have been found if it is inside the region, or within a 34 meter zone outside the region boundaries (see diagram). A single valid result may be returned after the avatar leaves this zone.<br />
<br />
<h5 style="margin:0;">{{LSLP|params}} Parameter</h5><br />
The {{LSLP|params}} list is used to indicate the object attributes of interest. The order they are supplied in determines the order of the corresponding return values in the return list.<br />
{{{!}} cellpadding="0" cellspacing="0"<br />
{{!}}<br />
*If {{LSLP|params}} contains unsupported integer values, {{LSL Const|OBJECT_UNKNOWN_DETAIL|integer|-1|c=}} is placed in the output list.<br />
*If {{LSLP|params}} contains non-[[integer]] types, those values will be silently ignored.<br />
{{!}}}<br />
<div style="clear:both;"></div><br />
|caveats=<br />
<br />
*[[OBJECT_ROT]] will return an accurate facing for Avatars seated or in mouselook, but only a rough direction otherwise.<br />
*Adjacent regions are not searched for prims which match {{LSLP|id}}.<br />
*Information for avatars that can no longer be found will still be available for a short period (about 45 seconds) but it is not updated.<br />
*Items in {{LSLP|params}} that are not integers are silently ignored, {{LSL Const|OBJECT_UNKNOWN_DETAIL|integer|-1|c=}} is not returned.<br />
*This function does not return information about items in inventory.<br />
*[[llTargetOmega]] will only effect the return of [[OBJECT_ROT]] if the object is [[STATUS_PHYSICS|physical]]. If the object is not physical then the original start rotation is returned, [[llTargetOmega]] is a {{LSLGC|Effects|client side effect}}.<br />
*{{LSL Const|OBJECT_SCRIPT_MEMORY|integer|11|c=}} reports the maximum memory that all scripts in an object could use, not the actual amount of real memory currently used. In particular, [[Mono]] scripts only report the default 64K or what they chose with [[llSetMemoryLimit]], not the current dynamic allocation that is only accessible from within the script. For [[LSO]] scripts, the 16K is real usage in all cases. In practice, this makes the number reported a worst case scenario.<br />
*{{LSL Const|OBJECT_RUNNING_SCRIPT_COUNT|integer|9|c=}} includes crashed scripts in its count.<br />
*{{LSL Const|OBJECT_REZZER_KEY|integer|32|c=}} will return [[NULL_KEY]] for objects rezzed prior to server version 16.01.16.310114<br />
*Objects copied in-world between server versions 16.01.16.310114 & 16.10.14.320687 return the object's creator key for rezzer key.<br />
*Child prims linked before server version 17.11.11.510664 return the root prim's rezzer key.<br />
*Child prims delinked before server version 17.11.11.510664 return NULL_KEY for rezzer key.<br />
*When targeting an agent with {{LSL Const|OBJECT_REZZER_KEY|integer|32|c=}} while they are sitting on an object, the rezzer key of the object's root prim is returned.<br />
|examples=<br />
<source lang="lsl2">default<br />
{<br />
collision_start(integer num_detected)<br />
{<br />
key id = llDetectedKey(0);<br />
list details = llGetObjectDetails(id, ([OBJECT_NAME, OBJECT_DESC,<br />
OBJECT_POS, OBJECT_ROT, OBJECT_VELOCITY,<br />
OBJECT_OWNER, OBJECT_GROUP, OBJECT_CREATOR]));<br />
llShout(PUBLIC_CHANNEL, "UUID: " + (string)id<br />
+ "\nName: " + llList2String(details, 0)<br />
+ "\nDescription: " + llList2String(details, 1)<br />
+ "\nPosition: " + llList2String(details, 2)<br />
+ "\nRotation: " + llList2String(details, 3)<br />
+ "\nVelocity: " + llList2String(details, 4)<br />
+ "\nOwner: " + llList2String(details, 5)<br />
+ "\nGroup: " + llList2String(details, 6)<br />
+ "\nCreator: " + llList2String(details, 7));<br />
}<br />
}</source><br />
<source lang="lsl2"><br />
// group join inviter<br />
// gets the name of the object's active group from the online group profile<br />
<br />
key groupNameRequestId;<br />
key groupKey;<br />
string groupName;<br />
<br />
init()<br />
{<br />
// WARNING:<br />
// different prims can have different active groups!!!<br />
<br />
// get the key of the root prim's group<br />
groupKey = llList2Key(llGetObjectDetails(llGetLinkKey(LINK_ROOT), [OBJECT_GROUP]), 0);<br />
<br />
// request the name of the root prim's group<br />
groupNameRequestId = llHTTPRequest("http://world.secondlife.com/group/" + (string)groupKey, [], "");<br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
init();<br />
}<br />
<br />
touch_start(integer num_detected)<br />
{<br />
if (groupKey == NULL_KEY || groupName == "")<br />
return;<br />
<br />
key id = llDetectedKey(0);<br />
llInstantMessage(id,<br />
"Click the link to join the group '" + groupName + "'\n"<br />
+ "secondlife:///app/group/" + (string)groupKey + "/about");<br />
}<br />
<br />
http_response(key request_id, integer status, list metadata, string body)<br />
{<br />
if (request_id != groupNameRequestId)<br />
return;<br />
<br />
list args = llParseString2List(body, ["title"], []);<br />
groupName = llList2String(llParseString2List(llList2String(args, 1), [">", "<", "/"], []), 0);<br />
}<br />
}<br />
</source><br />
<source lang="lsl2">// aim & shoot<br />
default<br />
{ state_entry()<br />
{ llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS);<br />
}<br />
control(key id, integer pressed, integer change) <br />
{ if(change & pressed & CONTROL_ML_LBUTTON)<br />
llSensor("", "", AGENT|PASSIVE|ACTIVE, 96.0, PI/16.0);<br />
}<br />
run_time_permissions(integer perm)<br />
{ if(perm&PERMISSION_TAKE_CONTROLS)<br />
llTakeControls(CONTROL_ML_LBUTTON, TRUE, TRUE); <br />
}<br />
sensor(integer n)<br />
{ key uuid=llDetectedKey(0);<br />
list a = llGetObjectDetails(uuid, ([<br />
OBJECT_NAME, OBJECT_DESC, OBJECT_POS, OBJECT_ROT,<br />
OBJECT_VELOCITY,OBJECT_OWNER, OBJECT_GROUP, OBJECT_CREATOR]));<br />
llOwnerSay("UUID: " + (string)uuid +<br />
"\nName: \"" + llList2String(a,0)+ "\"" +<br />
"\nDecription: \"" + llList2String(a,1) + "\"" +<br />
"\nPosition: " + llList2String(a,2) +<br />
"\nRotation: " + llList2String(a,3) +<br />
"\nVelocity: " + llList2String(a,4) +<br />
"\nOwner: " + llList2String(a,5) +<br />
"\nGroup: " + llList2String(a,6) +<br />
"\nCreator: " + llList2String(a,7)<br />
);<br />
}<br />
}</source><br />
<source lang="lsl2">// Object Script Time<br />
default<br />
{<br />
touch_start(integer num_detected)<br />
{<br />
llOwnerSay(llGetObjectName()+" Script Time: "+llList2String(llGetObjectDetails(llGetKey(), [OBJECT_SCRIPT_TIME]), 0));<br />
}<br />
}<br />
</source><br />
|spec<br />
|constants={{LSL Constants/Object Details}}<br />
|helpers=See {{LSLGC|Link/Get}} for some {{LSLGC|Link|link}} related helper functions. Also see [[llGetLinkPrimitiveParams]] if you need to get the position and rotation of a linked prim.<br />
<source lang="lsl2"><br />
integer isLindenTreeOrGrass(key id){<br />
//Check if it's an OPT_OTHER and not an attachment, which makes it a Linden tree or grass!<br />
list out = llGetObjectDetails(id, [OBJECT_PATHFINDING_TYPE, OBJECT_ATTACHED_POINT]);<br />
return (llList2Integer(out, 0) == OPT_OTHER) && !llList2Integer(out, 1);<br />
}<br />
</source><br />
|also_functions={{LSL DefineRow||[[llKey2Name]]}}<br />
{{LSL DefineRow||[[llGetPrimitiveParams]]}}<br />
{{LSL DefineRow||[[llSetLinkPrimitiveParams]]}}<br />
{{LSL DefineRow||[[llSetPrimitiveParams]]}}<br />
{{LSL DefineRow||[[llGetParcelDetails]]}}<br />
|also_tests<br />
|also_events<br />
|also_articles={{LSL DefineRow||{{LSLGC|Detected}}}}<br />
{{LSL DefineRow||[[Prim Attribute Overloading]]}}<br />
|notes<br />
|history=<br />
{{HistoryRow|2007|SL 1.18.3(2)|Introduced}}<br />
{{HistoryRow|28-09-2007|SL [[Release_Notes/Second_Life_Release/1.18#Release_Notes_for_Second_Life_1.18.3.285.29_September_28.2C_2007 | 1.18.3.285.29]]|Released}}<br />
|cat1=Object<br />
|cat2=Prim<br />
|cat3=Avatar<br />
|cat4=Owner<br />
|cat5=Creator<br />
|cat6=Group<br />
|cat7=Link<br />
|cat8=Click Action<br />
}}</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1209935User:Toady Nakamura2021-03-05T23:24:14Z<p>Toady Nakamura: comment</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Curates basic SL Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
|-<br />
||[[User:Toady Nakamura/Owner_Only|Owner (& friends) Only]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Responds to the touch of owner, owner & friends, or not at all!<br />
|-<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Ribbon Particle|Rainbow Ribbon Tail to Wear]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Rainbow particle tail to wear.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, object says new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
<br />
|-{{Hl2}}<br />
! '''Chatbots'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/ELIZA_chatbot|ELIZA_chatbot]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Eliza is a legendary 1966 computer program written by Joseph Weizenbaum. Here it is for LSL.<br />
|-<br />
||[[User:Toady Nakamura/LindenAIML|LindenAIML]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language).<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1209934User:Toady Nakamura2021-03-05T23:22:18Z<p>Toady Nakamura: /* Useful Scripts */</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
|-<br />
||[[User:Toady Nakamura/Owner_Only|Owner (& friends) Only]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Responds to the touch of owner, owner & friends, or not at all!<br />
|-<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Ribbon Particle|Rainbow Ribbon Tail to Wear]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Rainbow particle tail to wear.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, object says new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
<br />
|-{{Hl2}}<br />
! '''Chatbots'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/ELIZA_chatbot|ELIZA_chatbot]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Eliza is a legendary 1966 computer program written by Joseph Weizenbaum. Here it is for LSL.<br />
|-<br />
||[[User:Toady Nakamura/LindenAIML|LindenAIML]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language).<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1209933User:Toady Nakamura2021-03-05T23:20:59Z<p>Toady Nakamura: /* Useful Scripts */ fix oops</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
|-<br />
||[[User:Toady Nakamura/Owner_Only|Owner (& friends) Only]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Responds to the touch of owner, owner & friends, or not at all!<br />
|-<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Ribbon Particle|Rainbow Ribbon Tail to Wear]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Rainbow particle tail to wear.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
<br />
|-{{Hl2}}<br />
! '''Chatbots'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/ELIZA_chatbot|ELIZA_chatbot]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Eliza is a legendary 1966 computer program written by Joseph Weizenbaum. Here it is for LSL.<br />
|-<br />
||[[User:Toady Nakamura/LindenAIML|LindenAIML]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language).<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1209932User:Toady Nakamura2021-03-05T23:20:09Z<p>Toady Nakamura: /* Useful Scripts */ owner only</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
<br />
ser:Toady_Nakamura/Owner_Only<br />
|-<br />
||[[User:Toady Nakamura/Owner_Only|Owner Only]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Responds to the touch of owner, owner & friends, or not at all!<br />
|-<br />
<br />
<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Ribbon Particle|Rainbow Ribbon Tail to Wear]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Rainbow particle tail to wear.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
<br />
|-{{Hl2}}<br />
! '''Chatbots'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/ELIZA_chatbot|ELIZA_chatbot]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Eliza is a legendary 1966 computer program written by Joseph Weizenbaum. Here it is for LSL.<br />
|-<br />
||[[User:Toady Nakamura/LindenAIML|LindenAIML]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language).<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Owner_Only&diff=1209931User:Toady Nakamura/Owner Only2021-03-05T23:17:43Z<p>Toady Nakamura: added simpler example & more complicated one, prettier format</p>
<hr />
<div>If you want your object to only react to the owner, you need to get and use the owner's UUID key.<br />
<br />
Filter the key of the toucher against the owner's key by using the conditional format (if *what I got* == *the limiting factor*).<br />
<br />
== Example 1 - Congratulate owner ==<br />
<br />
The following example responds to owner's touch but does nothing at all if anyone else touches.<br />
if toucher key exactly equals owner's key - congratulate owner!<br />
<br />
<source lang="lsl2"><br />
default<br />
{ <br />
touch_start(integer num_detected)<br />
{<br />
if(llDetectedKey(0) == llGetOwner())<br />
{<br />
llRegionSayTo(owner, 0, "You alone can touch me!");<br />
}<br />
// the else nothing happens doesn't need to be defined<br />
}<br />
}<br />
}<br />
</source><br />
<br />
== Example 2 - If owner / else not owner ==<br />
This example shows how to define the owner's key, and provides an if/else conditional structure:<br />
* if toucher is owner, make box green, else make box red!<br />
<br />
<source lang="lsl2"><br />
key owner;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
owner = llGetOwner();<br />
}<br />
<br />
touch_start(integer num_detected)<br />
{<br />
if(llDetectedKey(0) == owner)<br />
{<br />
llSetColor(<0,1,0>, ALL_SIDES); // green<br />
}<br />
else<br />
{ <br />
llSetColor(<1,0,0>, ALL_SIDES); // red<br />
}<br />
}<br />
<br />
changed(integer change)<br />
{ <br />
if (change & CHANGED_OWNER)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
</source><br />
<br />
== Example 3 - If owner or friend/ else if other friend/ else none of the above ==<br />
<br />
This example shows one way to code different behaviors for different keys.<br />
<br />
<source lang="lsl2"><br />
key owner;<br />
key friend_key = "000000000000000000000"; // use a real key here!!<br />
key friend2_key ="9999999999999999999999";// use a real key here!!<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
owner = llGetOwner();<br />
}<br />
<br />
touch_start(integer num_detected)<br />
{<br />
key toucher = llDetectedKey(0);<br />
<br />
if(toucher == owner || toucher == friend_key) // either you or first friend<br />
{<br />
llSetColor(<0,1,0>, ALL_SIDES); // green<br />
}<br />
<br />
else if(toucher == friend2_key); // if second friend<br />
{<br />
llSetColor(<1,1,0>, ALL_SIDES); // yellow<br />
}<br />
else // anybody else<br />
{<br />
llSetColor(<1,0,0>, ALL_SIDES); // red<br />
}<br />
}<br />
<br />
changed(integer change)<br />
{ <br />
if (change & CHANGED_OWNER)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
</source><br />
<br />
==* Why two == or two || ? ==<br />
Because the if/else comparison is only TRUE/FALSE, the [[LSL_Operators Math Operators (symbols)]] are [[Boolean]]. Boolean Logic works on three Boolean Operators: “Or,” “And,” and “Not”. Using those three, all results of Boolean Logic resolve as either TRUE (1) or FALSE (0). You can compare positively as we do here, or compare to a negative by using ''if (toucher_key != owner)'' format. <br />
<br />
==* Why do two examples have the [[Changed|changed event]]?==<br />
'''Example 1 does not have changed event''' because script checks for owner after every touch. Which works but is not ideal.<br />
<br />
'''Examples 2 & 3 do have changed events''' because script checks once in state_entry and stores the answer. <br />
If the item changes to new owner, it resets and gets the new owner's UUIDkey.<br />
<br />
There are other "for owner only" tricks! See the simple listener example!<br />
---------------------------------------------------------------------------<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Owner_Only&diff=1209930User:Toady Nakamura/Owner Only2021-03-05T22:35:52Z<p>Toady Nakamura: new page for owner only conditionals... will add more</p>
<hr />
<div>If you want your object to only react to the owner, you need to get and use the owner's UUID key.<br />
<br />
Filter the key of the toucher against the owner's key by using the conditional format (if *what I got* == *the limiting factor*).<br />
<br />
This example of how to do it shows that if toucher is owner, make box green, else make box red!<br />
<br />
<source lang="lsl2"><br />
<br />
key owner;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
owner = llGetOwner();<br />
}<br />
<br />
touch_start(integer num_detected)<br />
{<br />
if(llDetectedKey(0) == owner)<br />
{<br />
llSetColor(<0,1,0>, ALL_SIDES);<br />
}<br />
else<br />
{<br />
llSetColor(<1,0,0>, ALL_SIDES);<br />
}<br />
}<br />
<br />
changed(integer change)<br />
{ <br />
if (change & CHANGED_OWNER)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
<br />
</source><br />
*changed event <br />
You need this event so if the item changes to new owner, it resets and gets the new owner's UUIDkey... otherwise it stays fixated on the first one it ever knew as its owner<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Visit my LSL wiki page for my library of simple scripts ! Toady Nakamura</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/ELIZA_chatbot&diff=1209927User:Toady Nakamura/ELIZA chatbot2021-03-03T20:09:16Z<p>Toady Nakamura: formatt2</p>
<hr />
<div>'''Eliza Chatbot'''<br />
''Sources & links at bottom of page! <br />
About ELIZA<br />
<br />
ELIZA is a famous 1966 computer program by Joseph Weizenbaum.<br />
<br />
ELIZA is a parody of a Rogerian therapist who rephrases many of the patient's statements as questions and poses them to the patient.<br />
<br />
'''Transcript of a sample conversation:'''<br />
<br />
You: hi<br />
<br />
Eliza Doolittle: how do you do--please state your problem.<br />
<br />
You: I don't have a problem<br />
<br />
Eliza Doolittle: does that trouble you?<br />
<br />
You: no<br />
<br />
Eliza Doolittle: you are being a bit negative.<br />
<br />
You: does that trouble you?<br />
<br />
Eliza Doolittle: we were discussing you-- not me.<br />
<br />
You: you have the problem.<br />
<br />
Eliza Doolittle: oh, I have the problem<br />
<br />
You: yes<br />
<br />
Eliza Doolittle: I see.<br />
<br />
<br />
<source lang="lsl2"><br />
// ELIZA is a famous 1966 computer program by Joseph Weizenbaum<br />
// ELIZA is a parody of a Rogerian therapist<br />
// ELIZA rephrases many of the patient's statements as questions and posing them to the patient.<br />
<br />
// This LSL version was originally ported by Dedric Mauriac<br />
// This LSL version is a port from a BASIC implementation written by John Schugg in January 1985.<br />
<br />
// Data Setup:<br />
// Keywords and patterns are contained in a seperate notecard<br />
// a keyword set appears on a line delimited with semi-colon and prefixed with number of responses<br />
// each response is written on its own line<br />
// if more then one response follows a set of keywords, a random response will be chosen<br />
// the last keyword in the notecard will always be used for responses that are not understood<br />
// blank lines should only appear before keywords or after the last response.<br />
// blank lines are optional and only used for easier management of data<br />
<br />
// how long to wait before responding and listening for next user input<br />
float delay = 7.5; <br />
<br />
// name of notecard containing patterns and responses<br />
string replyNote = "Chatbot.Eliza.txt";<br />
<br />
// stated when end-user repeats themselves<br />
string repeatReply = "please do not repeat yourself";<br />
<br />
// greeting<br />
string introduction = "Have any problems? Let me help you.";<br />
<br />
// don't listen to objects?<br />
integer ignoreObjects = TRUE;<br />
<br />
list keywords; // recognized keywords<br />
list matchStart; // start position in notecard for responses to each keyword<br />
list matchCount; // number of responses for each keyword<br />
integer lastLine;<br />
<br />
// number of lines in reply notecard<br />
integer replyLines;<br />
<br />
// id of request for notecard line count<br />
key replyCountId;<br />
<br />
// current line number being requested from notecard<br />
integer replyLine;<br />
<br />
// id of request for text in notecard for initialization<br />
key replyLineId;<br />
<br />
// characters recognized from user input<br />
string recognized = "abcdefghijklmnopqrstuvwxyz ";<br />
<br />
// id of listener for user input<br />
integer listener;<br />
<br />
// id of request for text in notecard as a response to input<br />
key responseId;<br />
<br />
string said; // what the user said<br />
string matched; // keyword/phrase the program understood<br />
<br />
integer processing = FALSE; // state if program is still processing last input<br />
<br />
string say; // response to user input<br />
<br />
initialize()<br />
{<br />
lastLine = -1;<br />
replyLine = 0;<br />
replyLines = -1;<br />
showProgress();<br />
keywords = [];<br />
matchCount = [];<br />
matchStart = [];<br />
replyCountId = llGetNumberOfNotecardLines(replyNote);<br />
}<br />
<br />
readReplies()<br />
{<br />
// at end of notecard?<br />
if(replyLine >= replyLines)<br />
{<br />
startSession();<br />
}<br />
else<br />
{ <br />
showProgress(); <br />
replyLineId = llGetNotecardLine(replyNote, replyLine++); // read next line<br />
}<br />
}<br />
<br />
initializeReply(string data)<br />
{<br />
data = llToLower(data);<br />
<br />
// is this a pattern?<br />
if(llSubStringIndex(data, ";") != -1)<br />
{<br />
list patterns = llParseString2List(data, [";"], []);<br />
integer count = llList2Integer(patterns, 0);<br />
keywords += llDeleteSubList(patterns, 0, 0);<br />
replyLine++;<br />
setMatchStart();<br />
setMatchLength(count);<br />
replyLine += count;<br />
}<br />
<br />
readReplies();<br />
}<br />
<br />
processMessage(string message)<br />
{<br />
// don't process if we are still working on the last message<br />
if(processing) return;<br />
processing = TRUE;<br />
<br />
message = formatMessage(message);<br />
<br />
// do not bother with repeat input<br />
if(said == message)<br />
{<br />
say = repeatReply;<br />
llSetTimerEvent(delay);<br />
return;<br />
}<br />
<br />
// remember what user said last<br />
said = message;<br />
<br />
// iterate through keywords<br />
integer n = llGetListLength(keywords);<br />
integer i;<br />
for(i = 0; i < n; i++)<br />
{<br />
// pad keyword with spaces<br />
string keyword = " " + llList2String(keywords, i) + " ";<br />
<br />
// if keyword in user-input, respond to it.<br />
if(llSubStringIndex(message, keyword) != -1)<br />
{<br />
respondTo(i);<br />
return;<br />
}<br />
}<br />
<br />
// since keyword not found, response with last keywords replies (not understood)<br />
respondTo(n - 1);<br />
}<br />
<br />
string formatMessage(string message)<br />
{ <br />
message = llToLower(message); // remove punctuation and change everything to lowercase<br />
string format = " ";<br />
integer i;<br />
integer n = llStringLength(message);<br />
<br />
for(i = 0; i < n; i++)<br />
{<br />
string char = llGetSubString(message, i, i);<br />
if(llSubStringIndex(recognized, char) != -1) format += char;<br />
}<br />
<br />
return format + " ";<br />
}<br />
<br />
respondTo(integer keywordIndex)<br />
{<br />
// determine what keyword to respond to<br />
matched = llList2String(keywords, keywordIndex);<br />
<br />
// determine what to respond with<br />
integer start = llList2Integer(matchStart, keywordIndex);<br />
integer count = llList2Integer(matchCount, keywordIndex);<br />
integer line = start + llFloor(llFrand(count));<br />
<br />
// prevent repeat response<br />
while(line == lastLine && count != 1)<br />
{<br />
line = start + llFloor(llFrand(count));<br />
}<br />
<br />
lastLine = line;<br />
<br />
// request text for chosen response<br />
responseId = llGetNotecardLine(replyNote, line);<br />
}<br />
<br />
string conjugateWord(string word)<br />
{<br />
// used to rephrase input into responses<br />
list conjugations = ["are", "am", <br />
"were", "was", <br />
"you", "i", <br />
"your", "my", <br />
"ive", "youve", <br />
"im", "youre", <br />
"you", "me"];<br />
<br />
// find word to replace<br />
integer i = llListFindList(conjugations, [word]);<br />
<br />
// not found<br />
if(i == -1) return word;<br />
<br />
// word found. opposites in pairs.<br />
if(i % 2 == 0) return llList2String(conjugations, i + 1);<br />
return llList2String(conjugations, i - 1);<br />
}<br />
<br />
string processConjugates()<br />
{<br />
// rephrase what user said after the matched keyword.<br />
<br />
integer i = llSubStringIndex(said, matched);<br />
string text = llGetSubString(said, i + llStringLength(matched), -1);<br />
list words = llParseString2List(text, [" "], []);<br />
text = "";<br />
<br />
integer n = llGetListLength(words);<br />
<br />
for(i = 0; i < n; i++)<br />
{<br />
text += " " + conjugateWord(llList2String(words, i));<br />
}<br />
<br />
return text;<br />
}<br />
<br />
processResponse(string message)<br />
{<br />
// format response<br />
message = llToLower(message);<br />
<br />
// if wildcard in response, rephrase what user said<br />
integer i = llSubStringIndex(message, "*");<br />
if(i != -1)<br />
{<br />
message = llDeleteSubString(message, i, i);<br />
message = llInsertString(message, i, processConjugates());<br />
}<br />
<br />
// prepare to respond<br />
say = message;<br />
llSetTimerEvent(delay);<br />
}<br />
<br />
showProgress()<br />
{<br />
// determine how much is done<br />
integer percent = (integer)(((float)replyLine / (float)replyLines) * 100);<br />
<br />
// build a text based progress bar - 59% [|||||......]<br />
string progress = (string)percent + "%\n[";<br />
integer i = 0;<br />
for(i = 0; i < 100; i+= 3)<br />
{<br />
if(i <= percent) progress += "|"; <br />
else progress += ".";<br />
}<br />
progress += "]";<br />
<br />
llSetText("Initializing\n" + progress, <1,1,1>, 1);<br />
}<br />
<br />
setMatchStart()<br />
{<br />
// set starting index for all keywords that do not yet have it set<br />
integer count = llGetListLength(keywords);<br />
integer i = llGetListLength(matchStart);<br />
for(; i < count; i++) matchStart += [replyLine - 1];<br />
}<br />
<br />
setMatchLength(integer length)<br />
{<br />
// determine number of replies for keyword set<br />
integer count = llGetListLength(keywords);<br />
integer i = llGetListLength(matchCount);<br />
for(; i < count; i++) matchCount += [length];<br />
}<br />
<br />
startSession()<br />
{<br />
// start listening<br />
llSetText("", ZERO_VECTOR, 0);<br />
if(listener != 0) llListenRemove(listener);<br />
listener = llListen(PUBLIC_CHANNEL, "", NULL_KEY, "");<br />
llSay(0, introduction);<br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
initialize();<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
initialize();<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if(change & CHANGED_INVENTORY) initialize();<br />
}<br />
<br />
dataserver(key queryId, string data) <br />
{<br />
if(queryId == replyCountId) // finding reply count<br />
{<br />
replyLines = (integer)data;<br />
readReplies();<br />
}<br />
else if(queryId == replyLineId) // initializing keywords/replies<br />
{<br />
initializeReply(data);<br />
}<br />
else if(queryId == responseId) // retrieving response template<br />
{<br />
processResponse(data);<br />
}<br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(!ignoreObjects && llGetOwnerKey(id) == id)<br />
{<br />
processMessage(message);<br />
}<br />
}<br />
<br />
touch_start(integer count)<br />
{<br />
llSay(0, introduction);<br />
}<br />
<br />
timer()<br />
{<br />
// say what we previously decided to say<br />
llSay(PUBLIC_CHANNEL, say);<br />
llSetTimerEvent(0);<br />
<br />
processing = FALSE; // listen for next input<br />
}<br />
}<br />
<br />
</source><br />
<br />
<br />
<br />
---- Make a notecard and put the following text into it for a sample!<br />
<source lang="lsl2"><br />
3;CAN YOU<br />
DON'T YOU BELIEVE THAT I CAN*<br />
PERHAPS YOU WOULD LIKE TO BE ABLE TO*<br />
YOU WANT ME TO BE ABLE TO*<br />
<br />
2;CAN I<br />
PERHAPS YOU DON'T WANT TO*<br />
DO YOU WANT TO BE ABLE TO*<br />
<br />
4;YOU ARE;YOURE<br />
WHAT MAKES YOU THINK I AM*<br />
DOES IT PLEASE YOU TO BELIEVE I AM*<br />
PERHAPS YOU WOULD LIKE TO BE*<br />
DO YOU SOMETIMES WISH YOU WERE*<br />
<br />
4;I DONT<br />
DON'T YOU REALLY*<br />
WHY DON'T YOU*<br />
DO YOU WISH TO BE ABLE TO*<br />
DOES THAT TROUBLE YOU?<br />
<br />
3;I FEEL<br />
TELL ME MORE ABOUT SUCH FEELINGS.<br />
DO YOU OFTEN FEEL*<br />
DO YOU ENJOY FEELING*<br />
<br />
3;WHY DONT YOU<br />
DO YOU REALLY BELIEVE I DON'T*<br />
PERHAPS IN GOOD TIME I WILL*<br />
DO YOU WANT ME TO*<br />
<br />
2;WHY CANT I<br />
DO YOU THINK YOU SHOULD BE ABLE TO*<br />
WHY CAN'T YOU*<br />
<br />
3;ARE YOU<br />
WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*<br />
WOULD YOU PREFER IF I WERE NOT*<br />
PERHAPS IN YOUR FANTASIES I AM*<br />
<br />
3;I CANT<br />
HOW DO YOU KNOW YOU CAN'T*<br />
HAVE YOU TRIED?<br />
PERHAPS YOU CAN NOW*<br />
<br />
4;I AM;IM<br />
DID YOU COME TO ME BECAUSE YOU ARE*<br />
HOW LONG HAVE YOU BEEN*<br />
DO YOU BELIEVE IT IS NORMAL TO BE*<br />
DO YOU ENJOY BEING*<br />
<br />
3;YOU<br />
WE WERE DISCUSSING YOU-- NOT ME.<br />
OH, I*<br />
YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?<br />
<br />
5;I WANT<br />
WHY DO YOU WANT*<br />
WHAT IF YOU NEVER GOT*<br />
I SOMETIMES ALSO WANT*<br />
WHAT WOULD IT MEAN TO YOU IF YOU GOT*<br />
SUPPOSE YOU SOON GOT*<br />
<br />
9;WHAT;HOW;WHO;WHERE;WHEN;WHY<br />
WHY DO YOU ASK?<br />
DOES THAT QUESTION INTEREST YOU?<br />
WHAT ANSWER WOULD PLEASE YOU THE MOST?<br />
WHAT DO YOU THINK?<br />
ARE SUCH QUESTIONS ON YOUR MIND OFTEN?<br />
WHAT IS IT THAT YOU REALLY WANT TO KNOW?<br />
HAVE YOU ASKED ANYONE ELSE?<br />
HAVE YOU ASKED SUCH QUESTIONS BEFORE?<br />
WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?<br />
<br />
2;NAME<br />
NAMES DON'T INTEREST ME.<br />
I DON'T CARE ABOUT NAMES-- PLEASE GO ON.<br />
<br />
4;CAUSE<br />
IS THAT THE REAL REASON?<br />
DON'T ANY OTHER REASONS COME TO MIND?<br />
DOES THAT REASON EXPLAIN ANY THING ELSE?<br />
WHAT OTHER REASONS MIGHT THERE BE?<br />
<br />
4;SORRY<br />
PLEASE DON'T APOLOGIZE.<br />
APOLOGIES ARE NOT NECESSARY.<br />
WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?<br />
DON'T BE SO DEFENSIVE!<br />
<br />
4;DREAM<br />
WHAT DOES THAT DREAM SUGGEST TO YOU?<br />
DO YOU DREAM OFTEN?<br />
WHAT PERSONS APPEAR IN YOUR DREAMS?<br />
ARE YOU DISTURBED BY YOUR DREAMS?<br />
<br />
1;HELLO;HI<br />
HOW DO YOU DO--PLEASE STATE YOUR PROBLEM.<br />
<br />
5;MAYBE<br />
YOU DON'T SEEM QUITE CERTAIN.<br />
WHY THE UNCERTAIN TONE?<br />
CAN'T YOU BE MORE POSITIVE?<br />
YOU AREN'T SURE?<br />
DON'T YOU KNOW?<br />
<br />
5;NO<br />
ARE YOU SAYING NO JUST TO BE NEGATIVE?<br />
YOU ARE BEING A BIT NEGATIVE.<br />
WHY NOT?<br />
ARE YOU SURE?<br />
WHY NO?<br />
<br />
2;YOUR<br />
WHY ARE YOU CONCERNED ABOUT MY*<br />
WHAT ABOUT YOUR OWN*<br />
<br />
4;ALWAYS<br />
CAN YOU THINK OF A SPECIFIC EXAMPLE?<br />
WHEN?<br />
WHAT ARE YOU THINKING OF?<br />
REALLY, ALWAYS?<br />
<br />
3;THINK<br />
DO YOU REALLY THINK SO?<br />
BUT YOU ARE NOT SURE YOU*<br />
DO YOU DOUBT YOU*<br />
<br />
7;ALIKE<br />
IN WHAT WAY?<br />
WHAT RESEMBLANCE DO YOU SEE?<br />
WHAT DOES THE SIMILARITY SUGGEST TO YOU?<br />
WHAT OTHER CONNECTIONS DO YOU SEE?<br />
COULD THERE REALLY BE SOME CONNECTION?<br />
HOW?<br />
YOU SEEM QUITE POSITIVE.<br />
<br />
3;YES<br />
ARE YOU SURE?<br />
I SEE.<br />
I UNDERSTAND.<br />
<br />
6;FRIEND<br />
WHY DO YOU BRING UP THE TOPIC OF FRIENDS?<br />
DO YOUR FRIENDS WORRY YOU?<br />
DO YOUR FRIENDS PICK ON YOU?<br />
ARE YOU SURE YOU HAVE ANY FRIENDS?<br />
DO YOU IMPOSE ON YOUR FRIENDS?<br />
PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU?<br />
<br />
7;COMPUTER<br />
DO COMPUTERS WORRY YOU?<br />
ARE YOU TALKING ABOUT ME IN PARTICULAR?<br />
ARE YOU FRIGHTENED BY MACHINES?<br />
WHY DO YOU MENTION COMPUTERS?<br />
WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?<br />
DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?<br />
WHAT IS IT ABOUT MACHINES THAT WORRIES YOU?<br />
<br />
5;CAR<br />
OH, DO YOU LIKE CARS?<br />
MY FAVORITE CAR IS A LAMBORGINI COUNTACH. WHAT IS YOUR FAVORITE CAR?<br />
MY FAVORITE CAR COMPANY IS FERRARI. WHAT IS YOURS?<br />
DO YOU LIKE PORSCHES?<br />
DO YOU LIKE PORSCHE TURBO CARRERAS?<br />
<br />
6;NOKEYFOUND<br />
SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS?<br />
WHAT DOES THAT SUGGEST TO YOU?<br />
I SEE.<br />
I'M NOT SURE I UNDERSTAND YOU FULLY.<br />
COME COME ELUCIDATE YOUR THOUGHTS.<br />
CAN YOU ELABORATE ON THAT?<br />
</source><br />
---- This ends the notecard, be sure there are no blank lines at the end of your card!<br />
<br />
'''External references'''<br />
<br />
[https://www.chegg.com/homework-help/questions-and-answers/eliza-famous-1966-computer-program-written-joseph-weizenbaum-imitates-psychologist-specifi-q24553990 about ELIZA]<br />
<br />
[https://en.wikipedia.org/wiki/ELIZA Wikipedia ELIZA]<br />
<br />
[http://lslwiki.digiworldz.com/lslwiki/wakka.php?wakka=LibraryElizaChatbot Defunct Wiki.wakka source]<br />
<br />
Visit my LSL wiki page for my library of scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/ELIZA_chatbot&diff=1209926User:Toady Nakamura/ELIZA chatbot2021-03-03T20:08:51Z<p>Toady Nakamura: formatt</p>
<hr />
<div>'''Eliza Chatbot'''<br />
''Sources & links at bottom of page! <br />
About ELIZA<br />
<br />
ELIZA is a famous 1966 computer program by Joseph Weizenbaum.<br />
<br />
ELIZA is a parody of a Rogerian therapist who rephrases many of the patient's statements as questions and poses them to the patient.<br />
<br />
'''Transcript of a sample conversation:'''<br />
<br />
You: hi<br />
<br />
Eliza Doolittle: how do you do--please state your problem.<br />
<br />
You: I don't have a problem<br />
<br />
Eliza Doolittle: does that trouble you?<br />
<br />
You: no<br />
<br />
Eliza Doolittle: you are being a bit negative.<br />
<br />
You: does that trouble you?<br />
<br />
Eliza Doolittle: we were discussing you-- not me.<br />
<br />
You: you have the problem.<br />
<br />
Eliza Doolittle: oh, I have the problem<br />
<br />
You: yes<br />
<br />
Eliza Doolittle: I see.<br />
<br />
<br />
<source lang="lsl2"><br />
// ELIZA is a famous 1966 computer program by Joseph Weizenbaum<br />
// ELIZA is a parody of a Rogerian therapist<br />
// ELIZA rephrases many of the patient's statements as questions and posing them to the patient.<br />
<br />
// This LSL version was originally ported by Dedric Mauriac<br />
// This LSL version is a port from a BASIC implementation written by John Schugg in January 1985.<br />
<br />
// Data Setup:<br />
// Keywords and patterns are contained in a seperate notecard<br />
// a keyword set appears on a line delimited with semi-colon and prefixed with number of responses<br />
// each response is written on its own line<br />
// if more then one response follows a set of keywords, a random response will be chosen<br />
// the last keyword in the notecard will always be used for responses that are not understood<br />
// blank lines should only appear before keywords or after the last response.<br />
// blank lines are optional and only used for easier management of data<br />
<br />
// how long to wait before responding and listening for next user input<br />
float delay = 7.5; <br />
<br />
// name of notecard containing patterns and responses<br />
string replyNote = "Chatbot.Eliza.txt";<br />
<br />
// stated when end-user repeats themselves<br />
string repeatReply = "please do not repeat yourself";<br />
<br />
// greeting<br />
string introduction = "Have any problems? Let me help you.";<br />
<br />
// don't listen to objects?<br />
integer ignoreObjects = TRUE;<br />
<br />
list keywords; // recognized keywords<br />
list matchStart; // start position in notecard for responses to each keyword<br />
list matchCount; // number of responses for each keyword<br />
integer lastLine;<br />
<br />
// number of lines in reply notecard<br />
integer replyLines;<br />
<br />
// id of request for notecard line count<br />
key replyCountId;<br />
<br />
// current line number being requested from notecard<br />
integer replyLine;<br />
<br />
// id of request for text in notecard for initialization<br />
key replyLineId;<br />
<br />
// characters recognized from user input<br />
string recognized = "abcdefghijklmnopqrstuvwxyz ";<br />
<br />
// id of listener for user input<br />
integer listener;<br />
<br />
// id of request for text in notecard as a response to input<br />
key responseId;<br />
<br />
string said; // what the user said<br />
string matched; // keyword/phrase the program understood<br />
<br />
integer processing = FALSE; // state if program is still processing last input<br />
<br />
string say; // response to user input<br />
<br />
initialize()<br />
{<br />
lastLine = -1;<br />
replyLine = 0;<br />
replyLines = -1;<br />
showProgress();<br />
keywords = [];<br />
matchCount = [];<br />
matchStart = [];<br />
replyCountId = llGetNumberOfNotecardLines(replyNote);<br />
}<br />
<br />
readReplies()<br />
{<br />
// at end of notecard?<br />
if(replyLine >= replyLines)<br />
{<br />
startSession();<br />
}<br />
else<br />
{ <br />
showProgress(); <br />
replyLineId = llGetNotecardLine(replyNote, replyLine++); // read next line<br />
}<br />
}<br />
<br />
initializeReply(string data)<br />
{<br />
data = llToLower(data);<br />
<br />
// is this a pattern?<br />
if(llSubStringIndex(data, ";") != -1)<br />
{<br />
list patterns = llParseString2List(data, [";"], []);<br />
integer count = llList2Integer(patterns, 0);<br />
keywords += llDeleteSubList(patterns, 0, 0);<br />
replyLine++;<br />
setMatchStart();<br />
setMatchLength(count);<br />
replyLine += count;<br />
}<br />
<br />
readReplies();<br />
}<br />
<br />
processMessage(string message)<br />
{<br />
// don't process if we are still working on the last message<br />
if(processing) return;<br />
processing = TRUE;<br />
<br />
message = formatMessage(message);<br />
<br />
// do not bother with repeat input<br />
if(said == message)<br />
{<br />
say = repeatReply;<br />
llSetTimerEvent(delay);<br />
return;<br />
}<br />
<br />
// remember what user said last<br />
said = message;<br />
<br />
// iterate through keywords<br />
integer n = llGetListLength(keywords);<br />
integer i;<br />
for(i = 0; i < n; i++)<br />
{<br />
// pad keyword with spaces<br />
string keyword = " " + llList2String(keywords, i) + " ";<br />
<br />
// if keyword in user-input, respond to it.<br />
if(llSubStringIndex(message, keyword) != -1)<br />
{<br />
respondTo(i);<br />
return;<br />
}<br />
}<br />
<br />
// since keyword not found, response with last keywords replies (not understood)<br />
respondTo(n - 1);<br />
}<br />
<br />
string formatMessage(string message)<br />
{ <br />
message = llToLower(message); // remove punctuation and change everything to lowercase<br />
string format = " ";<br />
integer i;<br />
integer n = llStringLength(message);<br />
<br />
for(i = 0; i < n; i++)<br />
{<br />
string char = llGetSubString(message, i, i);<br />
if(llSubStringIndex(recognized, char) != -1) format += char;<br />
}<br />
<br />
return format + " ";<br />
}<br />
<br />
respondTo(integer keywordIndex)<br />
{<br />
// determine what keyword to respond to<br />
matched = llList2String(keywords, keywordIndex);<br />
<br />
// determine what to respond with<br />
integer start = llList2Integer(matchStart, keywordIndex);<br />
integer count = llList2Integer(matchCount, keywordIndex);<br />
integer line = start + llFloor(llFrand(count));<br />
<br />
// prevent repeat response<br />
while(line == lastLine && count != 1)<br />
{<br />
line = start + llFloor(llFrand(count));<br />
}<br />
<br />
lastLine = line;<br />
<br />
// request text for chosen response<br />
responseId = llGetNotecardLine(replyNote, line);<br />
}<br />
<br />
string conjugateWord(string word)<br />
{<br />
// used to rephrase input into responses<br />
list conjugations = ["are", "am", <br />
"were", "was", <br />
"you", "i", <br />
"your", "my", <br />
"ive", "youve", <br />
"im", "youre", <br />
"you", "me"];<br />
<br />
// find word to replace<br />
integer i = llListFindList(conjugations, [word]);<br />
<br />
// not found<br />
if(i == -1) return word;<br />
<br />
// word found. opposites in pairs.<br />
if(i % 2 == 0) return llList2String(conjugations, i + 1);<br />
return llList2String(conjugations, i - 1);<br />
}<br />
<br />
string processConjugates()<br />
{<br />
// rephrase what user said after the matched keyword.<br />
<br />
integer i = llSubStringIndex(said, matched);<br />
string text = llGetSubString(said, i + llStringLength(matched), -1);<br />
list words = llParseString2List(text, [" "], []);<br />
text = "";<br />
<br />
integer n = llGetListLength(words);<br />
<br />
for(i = 0; i < n; i++)<br />
{<br />
text += " " + conjugateWord(llList2String(words, i));<br />
}<br />
<br />
return text;<br />
}<br />
<br />
processResponse(string message)<br />
{<br />
// format response<br />
message = llToLower(message);<br />
<br />
// if wildcard in response, rephrase what user said<br />
integer i = llSubStringIndex(message, "*");<br />
if(i != -1)<br />
{<br />
message = llDeleteSubString(message, i, i);<br />
message = llInsertString(message, i, processConjugates());<br />
}<br />
<br />
// prepare to respond<br />
say = message;<br />
llSetTimerEvent(delay);<br />
}<br />
<br />
showProgress()<br />
{<br />
// determine how much is done<br />
integer percent = (integer)(((float)replyLine / (float)replyLines) * 100);<br />
<br />
// build a text based progress bar - 59% [|||||......]<br />
string progress = (string)percent + "%\n[";<br />
integer i = 0;<br />
for(i = 0; i < 100; i+= 3)<br />
{<br />
if(i <= percent) progress += "|"; <br />
else progress += ".";<br />
}<br />
progress += "]";<br />
<br />
llSetText("Initializing\n" + progress, <1,1,1>, 1);<br />
}<br />
<br />
setMatchStart()<br />
{<br />
// set starting index for all keywords that do not yet have it set<br />
integer count = llGetListLength(keywords);<br />
integer i = llGetListLength(matchStart);<br />
for(; i < count; i++) matchStart += [replyLine - 1];<br />
}<br />
<br />
setMatchLength(integer length)<br />
{<br />
// determine number of replies for keyword set<br />
integer count = llGetListLength(keywords);<br />
integer i = llGetListLength(matchCount);<br />
for(; i < count; i++) matchCount += [length];<br />
}<br />
<br />
startSession()<br />
{<br />
// start listening<br />
llSetText("", ZERO_VECTOR, 0);<br />
if(listener != 0) llListenRemove(listener);<br />
listener = llListen(PUBLIC_CHANNEL, "", NULL_KEY, "");<br />
llSay(0, introduction);<br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
initialize();<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
initialize();<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if(change & CHANGED_INVENTORY) initialize();<br />
}<br />
<br />
dataserver(key queryId, string data) <br />
{<br />
if(queryId == replyCountId) // finding reply count<br />
{<br />
replyLines = (integer)data;<br />
readReplies();<br />
}<br />
else if(queryId == replyLineId) // initializing keywords/replies<br />
{<br />
initializeReply(data);<br />
}<br />
else if(queryId == responseId) // retrieving response template<br />
{<br />
processResponse(data);<br />
}<br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(!ignoreObjects && llGetOwnerKey(id) == id)<br />
{<br />
processMessage(message);<br />
}<br />
}<br />
<br />
touch_start(integer count)<br />
{<br />
llSay(0, introduction);<br />
}<br />
<br />
timer()<br />
{<br />
// say what we previously decided to say<br />
llSay(PUBLIC_CHANNEL, say);<br />
llSetTimerEvent(0);<br />
<br />
processing = FALSE; // listen for next input<br />
}<br />
}<br />
<br />
</source><br />
<br />
<br />
<br />
---- Make a notecard and put the following text into it for a sample!<br />
<source lang="lsl2"><br />
3;CAN YOU<br />
DON'T YOU BELIEVE THAT I CAN*<br />
PERHAPS YOU WOULD LIKE TO BE ABLE TO*<br />
YOU WANT ME TO BE ABLE TO*<br />
<br />
2;CAN I<br />
PERHAPS YOU DON'T WANT TO*<br />
DO YOU WANT TO BE ABLE TO*<br />
<br />
4;YOU ARE;YOURE<br />
WHAT MAKES YOU THINK I AM*<br />
DOES IT PLEASE YOU TO BELIEVE I AM*<br />
PERHAPS YOU WOULD LIKE TO BE*<br />
DO YOU SOMETIMES WISH YOU WERE*<br />
<br />
4;I DONT<br />
DON'T YOU REALLY*<br />
WHY DON'T YOU*<br />
DO YOU WISH TO BE ABLE TO*<br />
DOES THAT TROUBLE YOU?<br />
<br />
3;I FEEL<br />
TELL ME MORE ABOUT SUCH FEELINGS.<br />
DO YOU OFTEN FEEL*<br />
DO YOU ENJOY FEELING*<br />
<br />
3;WHY DONT YOU<br />
DO YOU REALLY BELIEVE I DON'T*<br />
PERHAPS IN GOOD TIME I WILL*<br />
DO YOU WANT ME TO*<br />
<br />
2;WHY CANT I<br />
DO YOU THINK YOU SHOULD BE ABLE TO*<br />
WHY CAN'T YOU*<br />
<br />
3;ARE YOU<br />
WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*<br />
WOULD YOU PREFER IF I WERE NOT*<br />
PERHAPS IN YOUR FANTASIES I AM*<br />
<br />
3;I CANT<br />
HOW DO YOU KNOW YOU CAN'T*<br />
HAVE YOU TRIED?<br />
PERHAPS YOU CAN NOW*<br />
<br />
4;I AM;IM<br />
DID YOU COME TO ME BECAUSE YOU ARE*<br />
HOW LONG HAVE YOU BEEN*<br />
DO YOU BELIEVE IT IS NORMAL TO BE*<br />
DO YOU ENJOY BEING*<br />
<br />
3;YOU<br />
WE WERE DISCUSSING YOU-- NOT ME.<br />
OH, I*<br />
YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?<br />
<br />
5;I WANT<br />
WHY DO YOU WANT*<br />
WHAT IF YOU NEVER GOT*<br />
I SOMETIMES ALSO WANT*<br />
WHAT WOULD IT MEAN TO YOU IF YOU GOT*<br />
SUPPOSE YOU SOON GOT*<br />
<br />
9;WHAT;HOW;WHO;WHERE;WHEN;WHY<br />
WHY DO YOU ASK?<br />
DOES THAT QUESTION INTEREST YOU?<br />
WHAT ANSWER WOULD PLEASE YOU THE MOST?<br />
WHAT DO YOU THINK?<br />
ARE SUCH QUESTIONS ON YOUR MIND OFTEN?<br />
WHAT IS IT THAT YOU REALLY WANT TO KNOW?<br />
HAVE YOU ASKED ANYONE ELSE?<br />
HAVE YOU ASKED SUCH QUESTIONS BEFORE?<br />
WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?<br />
<br />
2;NAME<br />
NAMES DON'T INTEREST ME.<br />
I DON'T CARE ABOUT NAMES-- PLEASE GO ON.<br />
<br />
4;CAUSE<br />
IS THAT THE REAL REASON?<br />
DON'T ANY OTHER REASONS COME TO MIND?<br />
DOES THAT REASON EXPLAIN ANY THING ELSE?<br />
WHAT OTHER REASONS MIGHT THERE BE?<br />
<br />
4;SORRY<br />
PLEASE DON'T APOLOGIZE.<br />
APOLOGIES ARE NOT NECESSARY.<br />
WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?<br />
DON'T BE SO DEFENSIVE!<br />
<br />
4;DREAM<br />
WHAT DOES THAT DREAM SUGGEST TO YOU?<br />
DO YOU DREAM OFTEN?<br />
WHAT PERSONS APPEAR IN YOUR DREAMS?<br />
ARE YOU DISTURBED BY YOUR DREAMS?<br />
<br />
1;HELLO;HI<br />
HOW DO YOU DO--PLEASE STATE YOUR PROBLEM.<br />
<br />
5;MAYBE<br />
YOU DON'T SEEM QUITE CERTAIN.<br />
WHY THE UNCERTAIN TONE?<br />
CAN'T YOU BE MORE POSITIVE?<br />
YOU AREN'T SURE?<br />
DON'T YOU KNOW?<br />
<br />
5;NO<br />
ARE YOU SAYING NO JUST TO BE NEGATIVE?<br />
YOU ARE BEING A BIT NEGATIVE.<br />
WHY NOT?<br />
ARE YOU SURE?<br />
WHY NO?<br />
<br />
2;YOUR<br />
WHY ARE YOU CONCERNED ABOUT MY*<br />
WHAT ABOUT YOUR OWN*<br />
<br />
4;ALWAYS<br />
CAN YOU THINK OF A SPECIFIC EXAMPLE?<br />
WHEN?<br />
WHAT ARE YOU THINKING OF?<br />
REALLY, ALWAYS?<br />
<br />
3;THINK<br />
DO YOU REALLY THINK SO?<br />
BUT YOU ARE NOT SURE YOU*<br />
DO YOU DOUBT YOU*<br />
<br />
7;ALIKE<br />
IN WHAT WAY?<br />
WHAT RESEMBLANCE DO YOU SEE?<br />
WHAT DOES THE SIMILARITY SUGGEST TO YOU?<br />
WHAT OTHER CONNECTIONS DO YOU SEE?<br />
COULD THERE REALLY BE SOME CONNECTION?<br />
HOW?<br />
YOU SEEM QUITE POSITIVE.<br />
<br />
3;YES<br />
ARE YOU SURE?<br />
I SEE.<br />
I UNDERSTAND.<br />
<br />
6;FRIEND<br />
WHY DO YOU BRING UP THE TOPIC OF FRIENDS?<br />
DO YOUR FRIENDS WORRY YOU?<br />
DO YOUR FRIENDS PICK ON YOU?<br />
ARE YOU SURE YOU HAVE ANY FRIENDS?<br />
DO YOU IMPOSE ON YOUR FRIENDS?<br />
PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU?<br />
<br />
7;COMPUTER<br />
DO COMPUTERS WORRY YOU?<br />
ARE YOU TALKING ABOUT ME IN PARTICULAR?<br />
ARE YOU FRIGHTENED BY MACHINES?<br />
WHY DO YOU MENTION COMPUTERS?<br />
WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?<br />
DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?<br />
WHAT IS IT ABOUT MACHINES THAT WORRIES YOU?<br />
<br />
5;CAR<br />
OH, DO YOU LIKE CARS?<br />
MY FAVORITE CAR IS A LAMBORGINI COUNTACH. WHAT IS YOUR FAVORITE CAR?<br />
MY FAVORITE CAR COMPANY IS FERRARI. WHAT IS YOURS?<br />
DO YOU LIKE PORSCHES?<br />
DO YOU LIKE PORSCHE TURBO CARRERAS?<br />
<br />
6;NOKEYFOUND<br />
SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS?<br />
WHAT DOES THAT SUGGEST TO YOU?<br />
I SEE.<br />
I'M NOT SURE I UNDERSTAND YOU FULLY.<br />
COME COME ELUCIDATE YOUR THOUGHTS.<br />
CAN YOU ELABORATE ON THAT?<br />
</source><br />
---- This ends the notecard, be sure there are no blank lines at the end of your card!<br />
<br />
'''External references'''<br />
[https://www.chegg.com/homework-help/questions-and-answers/eliza-famous-1966-computer-program-written-joseph-weizenbaum-imitates-psychologist-specifi-q24553990 about ELIZA]<br />
<br />
[https://en.wikipedia.org/wiki/ELIZA Wikipedia ELIZA]<br />
<br />
[http://lslwiki.digiworldz.com/lslwiki/wakka.php?wakka=LibraryElizaChatbot Defunct Wiki.wakka source]<br />
<br />
Visit my LSL wiki page for my library of scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/ELIZA_chatbot&diff=1209925User:Toady Nakamura/ELIZA chatbot2021-03-03T20:05:54Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>'''Eliza Chatbot'''<br />
''Sources & links at bottom of page! <br />
About ELIZA<br />
<br />
ELIZA is a famous 1966 computer program by Joseph Weizenbaum<br />
ELIZA is a parody of a Rogerian therapist<br />
ELIZA rephrases many of the patient's statements as questions and posing them to the patient.<br />
<br />
'''Transcript of a sample conversation:'''<br />
<br />
''You: hi<br />
Eliza Doolittle: how do you do--please state your problem.<br />
You: i don't have a problem<br />
Eliza Doolittle: does that trouble you?<br />
You: no<br />
Eliza Doolittle: you are being a bit negative.<br />
You: does that trouble you?<br />
Eliza Doolittle: we were discussing you-- not me.<br />
You: you have the problem.<br />
Eliza Doolittle: oh, i have the problem<br />
You: yes<br />
Eliza Doolittle: i see.''<br />
<br />
<br />
<source lang="lsl2"><br />
// ELIZA is a famous 1966 computer program by Joseph Weizenbaum<br />
// ELIZA is a parody of a Rogerian therapist<br />
// ELIZA rephrases many of the patient's statements as questions and posing them to the patient.<br />
<br />
// This LSL version was originally ported by Dedric Mauriac<br />
// This LSL version is a port from a BASIC implementation written by John Schugg in January 1985.<br />
<br />
// Data Setup:<br />
// Keywords and patterns are contained in a seperate notecard<br />
// a keyword set appears on a line delimited with semi-colon and prefixed with number of responses<br />
// each response is written on its own line<br />
// if more then one response follows a set of keywords, a random response will be chosen<br />
// the last keyword in the notecard will always be used for responses that are not understood<br />
// blank lines should only appear before keywords or after the last response.<br />
// blank lines are optional and only used for easier management of data<br />
<br />
// how long to wait before responding and listening for next user input<br />
float delay = 7.5; <br />
<br />
// name of notecard containing patterns and responses<br />
string replyNote = "Chatbot.Eliza.txt";<br />
<br />
// stated when end-user repeats themselves<br />
string repeatReply = "please do not repeat yourself";<br />
<br />
// greeting<br />
string introduction = "Have any problems? Let me help you.";<br />
<br />
// don't listen to objects?<br />
integer ignoreObjects = TRUE;<br />
<br />
list keywords; // recognized keywords<br />
list matchStart; // start position in notecard for responses to each keyword<br />
list matchCount; // number of responses for each keyword<br />
integer lastLine;<br />
<br />
// number of lines in reply notecard<br />
integer replyLines;<br />
<br />
// id of request for notecard line count<br />
key replyCountId;<br />
<br />
// current line number being requested from notecard<br />
integer replyLine;<br />
<br />
// id of request for text in notecard for initialization<br />
key replyLineId;<br />
<br />
// characters recognized from user input<br />
string recognized = "abcdefghijklmnopqrstuvwxyz ";<br />
<br />
// id of listener for user input<br />
integer listener;<br />
<br />
// id of request for text in notecard as a response to input<br />
key responseId;<br />
<br />
string said; // what the user said<br />
string matched; // keyword/phrase the program understood<br />
<br />
integer processing = FALSE; // state if program is still processing last input<br />
<br />
string say; // response to user input<br />
<br />
initialize()<br />
{<br />
lastLine = -1;<br />
replyLine = 0;<br />
replyLines = -1;<br />
showProgress();<br />
keywords = [];<br />
matchCount = [];<br />
matchStart = [];<br />
replyCountId = llGetNumberOfNotecardLines(replyNote);<br />
}<br />
<br />
readReplies()<br />
{<br />
// at end of notecard?<br />
if(replyLine >= replyLines)<br />
{<br />
startSession();<br />
}<br />
else<br />
{ <br />
showProgress(); <br />
replyLineId = llGetNotecardLine(replyNote, replyLine++); // read next line<br />
}<br />
}<br />
<br />
initializeReply(string data)<br />
{<br />
data = llToLower(data);<br />
<br />
// is this a pattern?<br />
if(llSubStringIndex(data, ";") != -1)<br />
{<br />
list patterns = llParseString2List(data, [";"], []);<br />
integer count = llList2Integer(patterns, 0);<br />
keywords += llDeleteSubList(patterns, 0, 0);<br />
replyLine++;<br />
setMatchStart();<br />
setMatchLength(count);<br />
replyLine += count;<br />
}<br />
<br />
readReplies();<br />
}<br />
<br />
processMessage(string message)<br />
{<br />
// don't process if we are still working on the last message<br />
if(processing) return;<br />
processing = TRUE;<br />
<br />
message = formatMessage(message);<br />
<br />
// do not bother with repeat input<br />
if(said == message)<br />
{<br />
say = repeatReply;<br />
llSetTimerEvent(delay);<br />
return;<br />
}<br />
<br />
// remember what user said last<br />
said = message;<br />
<br />
// iterate through keywords<br />
integer n = llGetListLength(keywords);<br />
integer i;<br />
for(i = 0; i < n; i++)<br />
{<br />
// pad keyword with spaces<br />
string keyword = " " + llList2String(keywords, i) + " ";<br />
<br />
// if keyword in user-input, respond to it.<br />
if(llSubStringIndex(message, keyword) != -1)<br />
{<br />
respondTo(i);<br />
return;<br />
}<br />
}<br />
<br />
// since keyword not found, response with last keywords replies (not understood)<br />
respondTo(n - 1);<br />
}<br />
<br />
string formatMessage(string message)<br />
{ <br />
message = llToLower(message); // remove punctuation and change everything to lowercase<br />
string format = " ";<br />
integer i;<br />
integer n = llStringLength(message);<br />
<br />
for(i = 0; i < n; i++)<br />
{<br />
string char = llGetSubString(message, i, i);<br />
if(llSubStringIndex(recognized, char) != -1) format += char;<br />
}<br />
<br />
return format + " ";<br />
}<br />
<br />
respondTo(integer keywordIndex)<br />
{<br />
// determine what keyword to respond to<br />
matched = llList2String(keywords, keywordIndex);<br />
<br />
// determine what to respond with<br />
integer start = llList2Integer(matchStart, keywordIndex);<br />
integer count = llList2Integer(matchCount, keywordIndex);<br />
integer line = start + llFloor(llFrand(count));<br />
<br />
// prevent repeat response<br />
while(line == lastLine && count != 1)<br />
{<br />
line = start + llFloor(llFrand(count));<br />
}<br />
<br />
lastLine = line;<br />
<br />
// request text for chosen response<br />
responseId = llGetNotecardLine(replyNote, line);<br />
}<br />
<br />
string conjugateWord(string word)<br />
{<br />
// used to rephrase input into responses<br />
list conjugations = ["are", "am", <br />
"were", "was", <br />
"you", "i", <br />
"your", "my", <br />
"ive", "youve", <br />
"im", "youre", <br />
"you", "me"];<br />
<br />
// find word to replace<br />
integer i = llListFindList(conjugations, [word]);<br />
<br />
// not found<br />
if(i == -1) return word;<br />
<br />
// word found. opposites in pairs.<br />
if(i % 2 == 0) return llList2String(conjugations, i + 1);<br />
return llList2String(conjugations, i - 1);<br />
}<br />
<br />
string processConjugates()<br />
{<br />
// rephrase what user said after the matched keyword.<br />
<br />
integer i = llSubStringIndex(said, matched);<br />
string text = llGetSubString(said, i + llStringLength(matched), -1);<br />
list words = llParseString2List(text, [" "], []);<br />
text = "";<br />
<br />
integer n = llGetListLength(words);<br />
<br />
for(i = 0; i < n; i++)<br />
{<br />
text += " " + conjugateWord(llList2String(words, i));<br />
}<br />
<br />
return text;<br />
}<br />
<br />
processResponse(string message)<br />
{<br />
// format response<br />
message = llToLower(message);<br />
<br />
// if wildcard in response, rephrase what user said<br />
integer i = llSubStringIndex(message, "*");<br />
if(i != -1)<br />
{<br />
message = llDeleteSubString(message, i, i);<br />
message = llInsertString(message, i, processConjugates());<br />
}<br />
<br />
// prepare to respond<br />
say = message;<br />
llSetTimerEvent(delay);<br />
}<br />
<br />
showProgress()<br />
{<br />
// determine how much is done<br />
integer percent = (integer)(((float)replyLine / (float)replyLines) * 100);<br />
<br />
// build a text based progress bar - 59% [|||||......]<br />
string progress = (string)percent + "%\n[";<br />
integer i = 0;<br />
for(i = 0; i < 100; i+= 3)<br />
{<br />
if(i <= percent) progress += "|"; <br />
else progress += ".";<br />
}<br />
progress += "]";<br />
<br />
llSetText("Initializing\n" + progress, <1,1,1>, 1);<br />
}<br />
<br />
setMatchStart()<br />
{<br />
// set starting index for all keywords that do not yet have it set<br />
integer count = llGetListLength(keywords);<br />
integer i = llGetListLength(matchStart);<br />
for(; i < count; i++) matchStart += [replyLine - 1];<br />
}<br />
<br />
setMatchLength(integer length)<br />
{<br />
// determine number of replies for keyword set<br />
integer count = llGetListLength(keywords);<br />
integer i = llGetListLength(matchCount);<br />
for(; i < count; i++) matchCount += [length];<br />
}<br />
<br />
startSession()<br />
{<br />
// start listening<br />
llSetText("", ZERO_VECTOR, 0);<br />
if(listener != 0) llListenRemove(listener);<br />
listener = llListen(PUBLIC_CHANNEL, "", NULL_KEY, "");<br />
llSay(0, introduction);<br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
initialize();<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
initialize();<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if(change & CHANGED_INVENTORY) initialize();<br />
}<br />
<br />
dataserver(key queryId, string data) <br />
{<br />
if(queryId == replyCountId) // finding reply count<br />
{<br />
replyLines = (integer)data;<br />
readReplies();<br />
}<br />
else if(queryId == replyLineId) // initializing keywords/replies<br />
{<br />
initializeReply(data);<br />
}<br />
else if(queryId == responseId) // retrieving response template<br />
{<br />
processResponse(data);<br />
}<br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(!ignoreObjects && llGetOwnerKey(id) == id)<br />
{<br />
processMessage(message);<br />
}<br />
}<br />
<br />
touch_start(integer count)<br />
{<br />
llSay(0, introduction);<br />
}<br />
<br />
timer()<br />
{<br />
// say what we previously decided to say<br />
llSay(PUBLIC_CHANNEL, say);<br />
llSetTimerEvent(0);<br />
<br />
processing = FALSE; // listen for next input<br />
}<br />
}<br />
<br />
</source><br />
<br />
<br />
<br />
---- Make a notecard and put the following text into it for a sample!<br />
<source lang="lsl2"><br />
3;CAN YOU<br />
DON'T YOU BELIEVE THAT I CAN*<br />
PERHAPS YOU WOULD LIKE TO BE ABLE TO*<br />
YOU WANT ME TO BE ABLE TO*<br />
<br />
2;CAN I<br />
PERHAPS YOU DON'T WANT TO*<br />
DO YOU WANT TO BE ABLE TO*<br />
<br />
4;YOU ARE;YOURE<br />
WHAT MAKES YOU THINK I AM*<br />
DOES IT PLEASE YOU TO BELIEVE I AM*<br />
PERHAPS YOU WOULD LIKE TO BE*<br />
DO YOU SOMETIMES WISH YOU WERE*<br />
<br />
4;I DONT<br />
DON'T YOU REALLY*<br />
WHY DON'T YOU*<br />
DO YOU WISH TO BE ABLE TO*<br />
DOES THAT TROUBLE YOU?<br />
<br />
3;I FEEL<br />
TELL ME MORE ABOUT SUCH FEELINGS.<br />
DO YOU OFTEN FEEL*<br />
DO YOU ENJOY FEELING*<br />
<br />
3;WHY DONT YOU<br />
DO YOU REALLY BELIEVE I DON'T*<br />
PERHAPS IN GOOD TIME I WILL*<br />
DO YOU WANT ME TO*<br />
<br />
2;WHY CANT I<br />
DO YOU THINK YOU SHOULD BE ABLE TO*<br />
WHY CAN'T YOU*<br />
<br />
3;ARE YOU<br />
WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*<br />
WOULD YOU PREFER IF I WERE NOT*<br />
PERHAPS IN YOUR FANTASIES I AM*<br />
<br />
3;I CANT<br />
HOW DO YOU KNOW YOU CAN'T*<br />
HAVE YOU TRIED?<br />
PERHAPS YOU CAN NOW*<br />
<br />
4;I AM;IM<br />
DID YOU COME TO ME BECAUSE YOU ARE*<br />
HOW LONG HAVE YOU BEEN*<br />
DO YOU BELIEVE IT IS NORMAL TO BE*<br />
DO YOU ENJOY BEING*<br />
<br />
3;YOU<br />
WE WERE DISCUSSING YOU-- NOT ME.<br />
OH, I*<br />
YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?<br />
<br />
5;I WANT<br />
WHY DO YOU WANT*<br />
WHAT IF YOU NEVER GOT*<br />
I SOMETIMES ALSO WANT*<br />
WHAT WOULD IT MEAN TO YOU IF YOU GOT*<br />
SUPPOSE YOU SOON GOT*<br />
<br />
9;WHAT;HOW;WHO;WHERE;WHEN;WHY<br />
WHY DO YOU ASK?<br />
DOES THAT QUESTION INTEREST YOU?<br />
WHAT ANSWER WOULD PLEASE YOU THE MOST?<br />
WHAT DO YOU THINK?<br />
ARE SUCH QUESTIONS ON YOUR MIND OFTEN?<br />
WHAT IS IT THAT YOU REALLY WANT TO KNOW?<br />
HAVE YOU ASKED ANYONE ELSE?<br />
HAVE YOU ASKED SUCH QUESTIONS BEFORE?<br />
WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?<br />
<br />
2;NAME<br />
NAMES DON'T INTEREST ME.<br />
I DON'T CARE ABOUT NAMES-- PLEASE GO ON.<br />
<br />
4;CAUSE<br />
IS THAT THE REAL REASON?<br />
DON'T ANY OTHER REASONS COME TO MIND?<br />
DOES THAT REASON EXPLAIN ANY THING ELSE?<br />
WHAT OTHER REASONS MIGHT THERE BE?<br />
<br />
4;SORRY<br />
PLEASE DON'T APOLOGIZE.<br />
APOLOGIES ARE NOT NECESSARY.<br />
WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?<br />
DON'T BE SO DEFENSIVE!<br />
<br />
4;DREAM<br />
WHAT DOES THAT DREAM SUGGEST TO YOU?<br />
DO YOU DREAM OFTEN?<br />
WHAT PERSONS APPEAR IN YOUR DREAMS?<br />
ARE YOU DISTURBED BY YOUR DREAMS?<br />
<br />
1;HELLO;HI<br />
HOW DO YOU DO--PLEASE STATE YOUR PROBLEM.<br />
<br />
5;MAYBE<br />
YOU DON'T SEEM QUITE CERTAIN.<br />
WHY THE UNCERTAIN TONE?<br />
CAN'T YOU BE MORE POSITIVE?<br />
YOU AREN'T SURE?<br />
DON'T YOU KNOW?<br />
<br />
5;NO<br />
ARE YOU SAYING NO JUST TO BE NEGATIVE?<br />
YOU ARE BEING A BIT NEGATIVE.<br />
WHY NOT?<br />
ARE YOU SURE?<br />
WHY NO?<br />
<br />
2;YOUR<br />
WHY ARE YOU CONCERNED ABOUT MY*<br />
WHAT ABOUT YOUR OWN*<br />
<br />
4;ALWAYS<br />
CAN YOU THINK OF A SPECIFIC EXAMPLE?<br />
WHEN?<br />
WHAT ARE YOU THINKING OF?<br />
REALLY, ALWAYS?<br />
<br />
3;THINK<br />
DO YOU REALLY THINK SO?<br />
BUT YOU ARE NOT SURE YOU*<br />
DO YOU DOUBT YOU*<br />
<br />
7;ALIKE<br />
IN WHAT WAY?<br />
WHAT RESEMBLANCE DO YOU SEE?<br />
WHAT DOES THE SIMILARITY SUGGEST TO YOU?<br />
WHAT OTHER CONNECTIONS DO YOU SEE?<br />
COULD THERE REALLY BE SOME CONNECTION?<br />
HOW?<br />
YOU SEEM QUITE POSITIVE.<br />
<br />
3;YES<br />
ARE YOU SURE?<br />
I SEE.<br />
I UNDERSTAND.<br />
<br />
6;FRIEND<br />
WHY DO YOU BRING UP THE TOPIC OF FRIENDS?<br />
DO YOUR FRIENDS WORRY YOU?<br />
DO YOUR FRIENDS PICK ON YOU?<br />
ARE YOU SURE YOU HAVE ANY FRIENDS?<br />
DO YOU IMPOSE ON YOUR FRIENDS?<br />
PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU?<br />
<br />
7;COMPUTER<br />
DO COMPUTERS WORRY YOU?<br />
ARE YOU TALKING ABOUT ME IN PARTICULAR?<br />
ARE YOU FRIGHTENED BY MACHINES?<br />
WHY DO YOU MENTION COMPUTERS?<br />
WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?<br />
DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?<br />
WHAT IS IT ABOUT MACHINES THAT WORRIES YOU?<br />
<br />
5;CAR<br />
OH, DO YOU LIKE CARS?<br />
MY FAVORITE CAR IS A LAMBORGINI COUNTACH. WHAT IS YOUR FAVORITE CAR?<br />
MY FAVORITE CAR COMPANY IS FERRARI. WHAT IS YOURS?<br />
DO YOU LIKE PORSCHES?<br />
DO YOU LIKE PORSCHE TURBO CARRERAS?<br />
<br />
6;NOKEYFOUND<br />
SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS?<br />
WHAT DOES THAT SUGGEST TO YOU?<br />
I SEE.<br />
I'M NOT SURE I UNDERSTAND YOU FULLY.<br />
COME COME ELUCIDATE YOUR THOUGHTS.<br />
CAN YOU ELABORATE ON THAT?<br />
</ source><br />
---- This ends the notecard, be sure there are no blank lines at the end of your card!<br />
<br />
[https://www.chegg.com/homework-help/questions-and-answers/eliza-famous-1966-computer-program-written-joseph-weizenbaum-imitates-psychologist-specifi-q24553990 about ELIZA]<br />
[https://en.wikipedia.org/wiki/ELIZA Wikipedia ELIZA]<br />
[http://lslwiki.digiworldz.com/lslwiki/wakka.php?wakka=LibraryElizaChatbot Defunct Wiki.wakka source]<br />
<br />
Visit my LSL wiki page for my library of scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1209924User:Toady Nakamura2021-03-03T20:05:10Z<p>Toady Nakamura: /* Useful Scripts */ Chatbots</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Ribbon Particle|Rainbow Ribbon Tail to Wear]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Rainbow particle tail to wear.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
<br />
|-{{Hl2}}<br />
! '''Chatbots'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/ELIZA_chatbot|ELIZA_chatbot]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Eliza is a legendary 1966 computer program written by Joseph Weizenbaum. Here it is for LSL.<br />
|-<br />
||[[User:Toady Nakamura/LindenAIML|LindenAIML]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language).<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/LindenAIML&diff=1209923User:Toady Nakamura/LindenAIML2021-03-03T20:04:55Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language). AIML utilizes the fact that humans, in conversation, often return to the same patterns of speech again and again, varying the words that determine the sentences reference, while keeping the mechanical structures largely similar. AIML replaces these variable portions of utterances with wildcards and attempts to match patterns in speech based on the invariant portions of utterances. For more information, read about ALICE.<br />
True AIML is an XML compliant language, and resembles HTML more than anything else. LindenAIML, while not XML compliant at this writing, imports most of the more commonly used features of AIML while supplementing it with features created specifically for the Second Life platform.<br />
<br />
The basic code for the LindenAIML interpreter is as follows:<br />
<br />
<source lang="lsl2"><br />
//The following code was generated by Luciftias Neurocam and Azrael Baphomet.<br />
//It is freely distributable under the terms of the GNU public license.<br />
//Please report significant mods to either Azrael or Luciftias. Thank you.<br />
<br />
<br />
string gName="filename";<br />
key gQueryID;<br />
list AIMList;<br />
list REPLYList;<br />
string data; <br />
string newmessage;<br />
integer gLine;<br />
integer handle;<br />
integer touched=0;<br />
<br />
integer myParse(string message) <br />
{<br />
integer begin; //index of message string marking beginning of matched pattern<br />
integer begin2; <br />
integer begina; //as above<br />
integer chat_channel=0;<br />
integer check_line; //no longer implemented<br />
integer end; //length of matched pattern, so ending index actually begin+end-1<br />
integer end_tag;<br />
integer end2;<br />
integer end3;<br />
integer enda;<br />
integer error_cond=0; //use later<br />
integer i=0; //loop (line) number<br />
integer ind;<br />
integer ind2;<br />
integer j;<br />
integer lenaimlist; //length of AIMList<br />
integer lenclust;<br />
integer poundindex;<br />
integer reply_index=-1;<br />
integer s_ind;<br />
integer starindex; //beginning index of *ed expression in message<br />
list cl; //individual words in clusters parsed to individual list entries<br />
list cl_a;<br />
list cl_b;<br />
list cl2; //individual words in cluster2 blah blah blah<br />
list cluster_a;<br />
list cluster_b;<br />
list cluster2;//cluster of post * words<br />
list clusters; //first cluster of pre * words<br />
list headmsglist;<br />
list msglist; //string message as parsed to list, separated by " "<br />
list new_reply_list;<br />
list newmsglist;<br />
list poundlist;<br />
list prestarlist;<br />
list starlist;<br />
list startopoundlist; //grabs text between star and pound<br />
list tailmsglist; <br />
list temp_reply_list;<br />
list unparsed_clusters;<br />
string last_message; //not used yet<br />
string newmsg;<br />
string parsed_reply;<br />
string poundstring;<br />
string resp_line;<br />
string starstring; //string corresponding to *ed characters<br />
string string1;<br />
string tempmessage="";<br />
string unparsed_clusters_string;<br />
string unparsed_reply;<br />
<br />
//begin actual program<br />
integer punc_index=llStringLength(message);<br />
punc_index--;<br />
if(llGetSubString(message,punc_index,punc_index)=="." || llGetSubString(message,punc_index,punc_index)=="!" || llGetSubString(message,punc_index,punc_index)=="?")<br />
{<br />
message=llDeleteSubString(message,punc_index,punc_index);<br />
}<br />
lenaimlist=llGetListLength(AIMList);<br />
reply_index=-1;<br />
while(reply_index==-1 && i< lenaimlist)//for(i=0;i<lenaimlist;i++)<br />
{<br />
clusters=[]; <br />
cluster2=[];<br />
cl=[];<br />
cl2=[];<br />
//override loop: if this string occurs anywhere in input, ignore all other parsing and respond with template following override<br />
if(llSubStringIndex(llList2String(AIMList,i),"<override>")!=-1)<br />
{<br />
//strip out <override> and </override><br />
<br />
ind=llSubStringIndex(llList2String(AIMList,i),"<override>");<br />
string1=llDeleteSubString(llList2String(AIMList,i),ind,ind+9);<br />
ind2=llSubStringIndex(string1,"</override>");<br />
string override_string=llDeleteSubString(string1,ind2,ind2+10);//this now represents string to match to message<br />
if(llSubStringIndex(message,override_string)!=-1)<br />
{<br />
<br />
reply_index=i;<br />
}<br />
} <br />
<br />
<br />
//find clusters/cluster2 in AIMList entry<br />
if(llSubStringIndex(llList2String(AIMList,i),"<pattern>")!=-1)<br />
{<br />
//strip out <pattern> and </pattern> from every line<br />
ind=llSubStringIndex(llList2String(AIMList,i),"<pattern>");<br />
string1=llDeleteSubString(llList2String(AIMList,i),ind,ind+8);<br />
ind2=llSubStringIndex(string1,"</pattern>");<br />
string unparsed_clusters_string=llDeleteSubString(string1,ind2,ind2+9);//this now represents string to match to message<br />
if(llSubStringIndex(unparsed_clusters_string,"*")!=-1)// && llSubStringIndex(unparsed_clusters_string,"#")==-1) //parse only lines using wildcard this way. non-wildcard parse follows<br />
{<br />
unparsed_clusters=llParseString2List(unparsed_clusters_string,["*"],[]); //break into 2 clusters, before * and after *<br />
<br />
<br />
<br />
lenclust=llGetListLength(unparsed_clusters);<br />
//unparsed_clusters=llDeleteSubList(unparsed_clusters,lenclust,lenclust);//what does this do? <br />
clusters=llList2List(unparsed_clusters,0,0); //Before * cluster <br />
cluster2=llList2List(unparsed_clusters,1,1);//after * cluster<br />
if(llSubStringIndex(unparsed_clusters_string,"*")==0)<br />
{<br />
cluster2=clusters;<br />
clusters=[];<br />
}<br />
cl=llParseString2List( (string) clusters,[" "],[]); //breaks out individual words in clusters<br />
cl2=llParseString2List( (string) cluster2,[" "],[]); //breaks out individual words in cluster2<br />
msglist=llParseString2List(message,[" "],[]); //breaks up input message into list of individual words. <br />
if(cl2==[])<br />
cl2=["asdfasfads"]; //insert unmatcheable value into cl2<br />
if(cl==[]) <br />
cl=["hgsjgh"];<br />
<br />
//Case of cluster *<br />
if(llListFindList(msglist,cl)!=-1 && llListFindList(msglist,cl2)==-1)<br />
{<br />
<br />
begin =llListFindList(msglist,cl); //find cl in msglist<br />
end=llGetListLength(cl);<br />
end--;<br />
tailmsglist=llDeleteSubList(msglist,begin,begin+end); //return only * and post * words<br />
<br />
starindex=llListFindList(msglist,tailmsglist); //locates *<br />
end2=llGetListLength(msglist);<br />
end2--; <br />
//if(end>=0 && begin>=0 && starindex >=0 && end2>=0) //so no negative indexes<br />
// newmsg=llDumpList2String(llListReplaceList(msglist,["*"],starindex,starindex+end2)," "); //replaces phrase with * in message<br />
//what to replace * with in reply<br />
starlist=llList2List(msglist,starindex,starindex+end2);<br />
<br />
//check similarity of matched pattern with message string<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)==cl+"*")<br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," "); <br />
}<br />
}<br />
<br />
//Case of * cluster2<br />
if(llListFindList(msglist,cl)==-1 && llListFindList(msglist,cl2)!=-1)<br />
{ <br />
begin=llListFindList(msglist,cl2);<br />
end=llGetListLength(cl2);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin, begin+end);<br />
starindex=llListFindList(msglist,headmsglist);<br />
end2=llGetListLength(headmsglist);<br />
end2--;<br />
//if(end>=0 && begin >=0 && starindex>=0 && end2>=0)<br />
// new<br />
starlist=llList2List(msglist, starindex, starindex+end2);<br />
starstring=llDumpList2String(starlist," ");<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)=="*"+cl2)<br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
<br />
}<br />
}<br />
<br />
//Case of clusters * cluster2<br />
if(llListFindList(msglist,cl)!=-1 && llListFindList(msglist,cl2)!=-1)<br />
{<br />
//first delete clusters from message<br />
<br />
begin=llListFindList(msglist, cl);<br />
end=llGetListLength(cl);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin,begin+end);<br />
<br />
//then delete cluster2 from tailmsglist<br />
begina =llListFindList(headmsglist, cl2);<br />
enda=llGetListLength(cl2);<br />
enda--;<br />
starlist=llDeleteSubList(headmsglist,begina,begina+enda);<br />
starindex=llListFindList(msglist,starlist);<br />
end2=llGetListLength(starlist);<br />
end2--;<br />
// starstring=llDumpList2String(starlist," ");<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)==cl+"*"+cl2 ) <br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
}<br />
}<br />
//case of cluster * cluster_a # cluster_b<br />
if(llSubStringIndex(unparsed_clusters_string,"#")!=-1)<br />
{<br />
////first delete clusters from message<br />
<br />
begin=llListFindList(msglist, cl);<br />
end=llGetListLength(cl);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin,begin+end);<br />
prestarlist=llList2List(msglist,begin,begin+end);<br />
//parse cluster2 into cluster_a and cluster_b<br />
startopoundlist=llParseString2List((string) cluster2, ["#"],[]);<br />
cluster_a=llList2List(startopoundlist,0,0);<br />
list cl_a=llParseString2List( (string) cluster_a,[" "],[]);<br />
//then delete cl_a from tailmsglist<br />
<br />
begina =llListFindList(headmsglist, cl_a);<br />
enda=llGetListLength(cl_a);<br />
enda--;<br />
<br />
<br />
//replace starlist in msglist first;<br />
integer endb=llGetListLength(headmsglist);<br />
starlist=llDeleteSubList(headmsglist,begina,endb--);<br />
starindex=llListFindList(msglist,starlist);<br />
end2=llGetListLength(starlist);<br />
end2--;<br />
//newmsglist=llListReplaceList(tailmsglist,["*"],starindex,starindex+end2);<br />
if(llGetListLength(startopoundlist)>1)<br />
{<br />
cluster_b=llList2List(startopoundlist,1,1);<br />
cl_b=llParseString2List( (string) cluster_b,[" "],[]);<br />
//find index of cl_b in msglist<br />
integer clbstart=llListFindList(headmsglist,llParseString2List((string) llList2List(startopoundlist,1,1),[" "],[])); //delete all but this<br />
integer lenmsglist=llGetListLength(headmsglist);<br />
poundlist=llDeleteSubList(headmsglist,clbstart,lenmsglist--); <br />
enda=llGetListLength(llParseString2List( (string) llList2List(startopoundlist,0,0),[" "],[]));<br />
poundlist=llDeleteSubList(poundlist,0,enda--) ;<br />
}<br />
<br />
//integer endb=llGetListLength(headmsglist);<br />
// starlist=llDeleteSubList(headmsglist,begina,endb--);<br />
<br />
<br />
starindex=llListFindList(msglist,starlist);<br />
<br />
// <br />
integer starlength=llGetListLength(starlist);<br />
starlength--;<br />
newmsglist=llListReplaceList(msglist,["*"],starindex,starindex+starlength--);<br />
integer poundindex=llListFindList(newmsglist,poundlist);<br />
integer poundlength=llGetListLength(poundlist);<br />
poundlength--;<br />
newmsglist=llListReplaceList(newmsglist,["#"],poundindex,poundindex+poundlength--);<br />
if(newmsglist==cl+["*"]+cl_a+["#"]+cl_b) <br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
poundstring=llDumpList2String(poundlist," ");<br />
}<br />
<br />
}<br />
}<br />
else<br />
{<br />
if(unparsed_clusters_string==message)<br />
reply_index=i;<br />
}<br />
}<br />
<br />
i++;<br />
<br />
}<br />
<br />
if(reply_index!=-1) //if a match exists<br />
{ <br />
if(llSubStringIndex(llList2String(AIMList,reply_index+1),"<channel>")!=-1)<br />
{<br />
ind=llSubStringIndex(llList2String(AIMList,reply_index+1),"<channel>");<br />
string1=llDeleteSubString(llList2String(AIMList,reply_index+1),ind,ind+8);<br />
ind2=llSubStringIndex(string1,"</channel>");<br />
string chat_channel_string=llDeleteSubString(string1,ind2,ind2+9); <br />
chat_channel=(integer) chat_channel_string;<br />
<br />
}<br />
unparsed_reply=llList2String(REPLYList, reply_index);<br />
end_tag=llSubStringIndex(unparsed_reply,"</template>");<br />
end_tag--;<br />
parsed_reply=llGetSubString(unparsed_reply,10,end_tag--); //from end of <template> to </template><br />
if(llSubStringIndex(parsed_reply, "<star/>")==-1)<br />
{<br />
if(llSubStringIndex(parsed_reply,"<srai")==-1)<br />
{<br />
llSay(chat_channel,parsed_reply);<br />
<br />
reply_index=0;<br />
}<br />
else<br />
{<br />
error_cond=-1;<br />
integer lenp=llStringLength(parsed_reply); <br />
integer termin=lenp--;<br />
termin--;termin--;termin--;termin--;termin--;termin--;termin--;termin--;<br />
// integer starindex2=llSubStringIndex(parsed_reply,"<star/>");<br />
// starindex2--;<br />
//if(starindex2!=-1)<br />
//{<br />
// parsed_reply=llGetSubString(parsed_reply,6,starindex) +" " +starstring;<br />
//}<br />
//else<br />
//{<br />
<br />
newmessage=llGetSubString(parsed_reply,6,termin);<br />
// }<br />
}<br />
}<br />
else // if <star/> expression exists, insert antecedant<br />
{<br />
//if <pound/> expression exists<br />
if(llSubStringIndex(parsed_reply,"<poun")!=-1)<br />
{<br />
temp_reply_list=llParseString2List(parsed_reply,[" "],[]); <br />
s_ind=llListFindList(temp_reply_list,["<pound/>"]);<br />
new_reply_list=llListReplaceList(temp_reply_list,[poundstring],s_ind,s_ind);<br />
parsed_reply=llDumpList2String(new_reply_list," ");<br />
llSay(0,(string)new_reply_list);<br />
<br />
}<br />
//else new_reply_list=llParseString2List(parsed_reply,[" "],[]);<br />
if(llSubStringIndex(parsed_reply,"<srai")==-1)<br />
{<br />
temp_reply_list=llParseString2List(parsed_reply,[" "],[]); <br />
integer s_ind2=llListFindList(temp_reply_list,["<star/>"]);<br />
temp_reply_list=llListReplaceList(temp_reply_list,[starstring],s_ind2,s_ind2);<br />
<br />
parsed_reply=llDumpList2String(temp_reply_list," ");<br />
llSay(chat_channel,parsed_reply);<br />
<br />
reply_index=0;<br />
}<br />
else <br />
{ <br />
//strip out <srai> tags<br />
integer srai_ind1=llSubStringIndex(parsed_reply,"<srai>");<br />
integer srai_ind2=llSubStringIndex(parsed_reply,"</srai>");<br />
//parsed_reply=llDeleteSubString(parsed_reply,srai_ind1,srai_ind1+5);<br />
<br />
parsed_reply=llGetSubString(parsed_reply,srai_ind1+6,srai_ind2-=1);<br />
//if pound expression exists<br />
if(llSubStringIndex(parsed_reply,"<poun")!=-1)<br />
{<br />
error_cond=-1; <br />
integer lenp=llStringLength(parsed_reply);<br />
integer termin=lenp--;<br />
integer poundindex2=llSubStringIndex(parsed_reply,"<pound/>");<br />
<br />
poundindex2--;<br />
if(poundindex2!=-1)<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,poundindex2) +poundstring;<br />
parsed_reply=llDeleteSubString(parsed_reply,poundindex2,poundindex2+8);<br />
parsed_reply=llInsertString(parsed_reply,poundindex,poundstring);<br />
//use llDeleteSubString followed by llInsertString<br />
}<br />
else<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,termin);<br />
<br />
}<br />
<br />
}<br />
error_cond=-1; <br />
<br />
integer lenp=llStringLength(parsed_reply);<br />
integer termin=lenp--;<br />
integer starindex2=llSubStringIndex(parsed_reply,"<star/>");<br />
starindex2--;<br />
if(starindex2!=-1)<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,starindex2) +starstring;<br />
parsed_reply=llDeleteSubString(parsed_reply,starindex2,starindex2+8);<br />
parsed_reply=llInsertString(parsed_reply,starindex,starstring);<br />
//use llDeleteSubString followed by llInsertString<br />
<br />
}<br />
else<br />
{<br />
newmessage=llGetSubString(parsed_reply,6,termin);<br />
<br />
}<br />
<br />
}<br />
<br />
}<br />
}<br />
else<br />
{<br />
llSay(0,"I'm afraid I don't understand what you said...yet");<br />
//email message to some address dedicated to receiving unmatched patterns. Uncomment line after inserting correct address<br />
//llEmail(address@whatever.com, "LindenAIML: New Template Needed", "no match for: " +message); // send email to self<br />
}<br />
return error_cond;<br />
}<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{<br />
llSetText("LindenAIML Concierge", <1,1,1>, 1.0);<br />
gQueryID=llGetNotecardLine(gName,gLine);//request first line<br />
gLine++; //increase line count<br />
}<br />
<br />
dataserver(key query_id,string data)<br />
{<br />
if(query_id==gQueryID)<br />
{ <br />
if(data!=EOF)<br />
{<br />
if( llGetSubString(data,0,3)=="<pat" || llGetSubString(data,0,3)=="<ove" || llGetSubString(data,0,3)=="<cha")<br />
{<br />
if(gLine==0) //for now ignore all but pattern or template lines<br />
{<br />
AIMList=(list) [data];<br />
} <br />
else<br />
{<br />
AIMList=AIMList + [data];<br />
}<br />
}<br />
if(llGetSubString(data,0,3)=="<tem" || llGetSubString(data,0,3)=="<cha" )<br />
{<br />
if(gLine==0) //for now ignore all but pattern or template lines <br />
{<br />
REPLYList=(list) [data];<br />
} <br />
else<br />
{<br />
REPLYList=REPLYList + [data];<br />
<br />
}<br />
<br />
}<br />
}<br />
gQueryID=llGetNotecardLine(gName,gLine); //request next line<br />
gLine++; <br />
}<br />
}<br />
<br />
touch_start(integer total_number)<br />
{<br />
<br />
<br />
if(touched==0)<br />
{<br />
handle=llListen(0,"",llGetOwner(),"");<br />
llSay(0,"AIML on");<br />
llGiveInventory(llDetectedKey(0), "LindenAIML");<br />
llGiveInventory(llDetectedKey(0), "LAIMLDocs");<br />
touched++;<br />
}<br />
else<br />
{<br />
llListenRemove(handle);<br />
llSay(0,"AIML off");<br />
touched=0;<br />
} <br />
<br />
}<br />
<br />
listen(integer channel, string name, key id, string msg)<br />
{<br />
<br />
integer error_cond=myParse(msg); <br />
if(error_cond==-1)<br />
{<br />
//message=newmessage;<br />
<br />
myParse(newmessage);<br />
}<br />
} <br />
}<br />
</source><br />
<br />
In addition to the LindenAIML interpreter code above, one also needs a “dialogue template” written in<br />
LindenAIML designed to coordinate responses to queries made on Second Life chat.<br />
<br />
The text below is intended to be incorporated as a notecard in an object containing the interpreter. This file, referred to as "filename" in the above code, contains the AIML tagged text to be used as a script for the interpreter. The syntax of LindenAIML is strict, as will be outlined below.<br />
<source lang="lsl2"><br />
<category><br />
<pattern>How are you *</pattern><br />
<template><star/> is fine</template><br />
</category><br />
<category><br />
<pattern>Are you well * bot</pattern><br />
<template>This <star/> bot is great</template><br />
</category><br />
<category><br />
<pattern>Who is *</pattern><br />
<template>I don't know, who is <star/></template><br />
</category><br />
<category><br />
<override>fish</override><br />
<template>I hate fish</template><br />
</category><br />
<category><br />
<pattern>Are there too many * in this sim</pattern><br />
<template>I don't know much about <star/></template><br />
</category><br />
<category><br />
<pattern>Are you OK * bot</pattern><br />
<template><srai>Are you well <star/> bot</srai></template><br />
</category><br />
<category><br />
<pattern>Reply on channel 1</pattern><br />
<template>OK</template><br />
<channel>1</channel><br />
</category><br />
<pattern>The * in spain falls mainly # the plain</pattern><br />
<template>That confounded <star/> falls mainly <pound/> that blasted plain</template><br />
</category><br />
</source><br />
<br />
A brief explication of the tags. As of this writing, the <category> tag is not used. In the future it will contain flags about topic and such like. But right now it's simply included to keep the LindenAIML file looking somewhat familiar to AIML users.<br />
<br />
The <pattern> tags contain patterns to match user utterances.<br />
The <template> tags contain hypothetical replies to the patterns.<br />
The <channel> tag (not included in every entry contained in <category></category> pair) allows the user to determin what channel the reply will occur on. So the bot can issue commands to other devices listening on those channels.<br />
<br />
<override> represents a special case of <pattern>. In the example, if the user says anything that contains the word "fish", the reply will be that in the <template></template> tags immediately following the <override></override> pair.<br />
<br />
<srai></srai> is the "syntactic reduction" tagpair. If a pattern produces a template with syntactic reduction tags enclosing the response, that responses is fed to the algorithm as a new user message to parse. The upshot of this: Patterns followed by <srai> tags are regarded as equivalent to the text contained in the <srai> tagpair, which should be defined elsewhere in the file (and by convention, previously in the file). Too many of these can slow operation considerably. Be warned.<br />
<br />
the <star/> tag is an isolated tag and represents the insertion point for phrases denoted by the wildcard "*" in the pattern to match. So If I say: "I hate you bot", and the pattern to match is "I * you bot", the template reply might be "Well, I <star/> you too.", resulting in a reply: "Well, I hate you too."<br />
<br />
A second wildcard has been implemented, using the “#” character. As with “*”, the “#” character will commonly replace the <pound/> tag in the reply string. As of this writing<br />
the second wildcard only processes patterns of the format "string1 * string2 # string3". Updates to LindenAIML will also allow the processing of patterns such as "* string #".<br />
<br />
Beware punctuation following <star/> or <pound/> tags. I have not, as yet, integrated that kind of punctuation into the parsing procedures. However, end of utterance punctuation is stripped from the user message at this point, so it is not necessary to include punctuation at the end of patterns.<br />
<br />
It is important to note that LindenAIML is sensitive to the format of the AIML file. No extra spaces between tags, and line-format should be as above. For example, if you put a space between the <pattern> tag and the first word of the actual pattern, you run the risk of confusing the interpreter. Also, tags must be lower case at this point. All tagsets except the <category></category> must be on the same line of text. In future versions, we hope to make LindenAIML more flexible sytlistically.<br />
<br />
-Azrael Baphomet and Luciftias Neurocam<br />
--copied from [http://lslwiki.digiworldz.com/lslwiki/wakka.php?wakka=LibraryLindenAIML] for the Linden Script Library.<br />
Visit my LSL wiki page for my library of scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/LindenAIML&diff=1209922User:Toady Nakamura/LindenAIML2021-03-03T20:03:00Z<p>Toady Nakamura: http://lslwiki.digiworldz.com/lslwiki/wakka.php?wakka=LibraryLindenAIML</p>
<hr />
<div>LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language). AIML utilizes the fact that humans, in conversation, often return to the same patterns of speech again and again, varying the words that determine the sentences reference, while keeping the mechanical structures largely similar. AIML replaces these variable portions of utterances with wildcards and attempts to match patterns in speech based on the invariant portions of utterances. For more information, read about ALICE.<br />
True AIML is an XML compliant language, and resembles HTML more than anything else. LindenAIML, while not XML compliant at this writing, imports most of the more commonly used features of AIML while supplementing it with features created specifically for the Second Life platform.<br />
<br />
The basic code for the LindenAIML interpreter is as follows:<br />
<br />
<source lang="lsl2"><br />
//The following code was generated by Luciftias Neurocam and Azrael Baphomet.<br />
//It is freely distributable under the terms of the GNU public license.<br />
//Please report significant mods to either Azrael or Luciftias. Thank you.<br />
<br />
<br />
string gName="filename";<br />
key gQueryID;<br />
list AIMList;<br />
list REPLYList;<br />
string data; <br />
string newmessage;<br />
integer gLine;<br />
integer handle;<br />
integer touched=0;<br />
<br />
integer myParse(string message) <br />
{<br />
integer begin; //index of message string marking beginning of matched pattern<br />
integer begin2; <br />
integer begina; //as above<br />
integer chat_channel=0;<br />
integer check_line; //no longer implemented<br />
integer end; //length of matched pattern, so ending index actually begin+end-1<br />
integer end_tag;<br />
integer end2;<br />
integer end3;<br />
integer enda;<br />
integer error_cond=0; //use later<br />
integer i=0; //loop (line) number<br />
integer ind;<br />
integer ind2;<br />
integer j;<br />
integer lenaimlist; //length of AIMList<br />
integer lenclust;<br />
integer poundindex;<br />
integer reply_index=-1;<br />
integer s_ind;<br />
integer starindex; //beginning index of *ed expression in message<br />
list cl; //individual words in clusters parsed to individual list entries<br />
list cl_a;<br />
list cl_b;<br />
list cl2; //individual words in cluster2 blah blah blah<br />
list cluster_a;<br />
list cluster_b;<br />
list cluster2;//cluster of post * words<br />
list clusters; //first cluster of pre * words<br />
list headmsglist;<br />
list msglist; //string message as parsed to list, separated by " "<br />
list new_reply_list;<br />
list newmsglist;<br />
list poundlist;<br />
list prestarlist;<br />
list starlist;<br />
list startopoundlist; //grabs text between star and pound<br />
list tailmsglist; <br />
list temp_reply_list;<br />
list unparsed_clusters;<br />
string last_message; //not used yet<br />
string newmsg;<br />
string parsed_reply;<br />
string poundstring;<br />
string resp_line;<br />
string starstring; //string corresponding to *ed characters<br />
string string1;<br />
string tempmessage="";<br />
string unparsed_clusters_string;<br />
string unparsed_reply;<br />
<br />
//begin actual program<br />
integer punc_index=llStringLength(message);<br />
punc_index--;<br />
if(llGetSubString(message,punc_index,punc_index)=="." || llGetSubString(message,punc_index,punc_index)=="!" || llGetSubString(message,punc_index,punc_index)=="?")<br />
{<br />
message=llDeleteSubString(message,punc_index,punc_index);<br />
}<br />
lenaimlist=llGetListLength(AIMList);<br />
reply_index=-1;<br />
while(reply_index==-1 && i< lenaimlist)//for(i=0;i<lenaimlist;i++)<br />
{<br />
clusters=[]; <br />
cluster2=[];<br />
cl=[];<br />
cl2=[];<br />
//override loop: if this string occurs anywhere in input, ignore all other parsing and respond with template following override<br />
if(llSubStringIndex(llList2String(AIMList,i),"<override>")!=-1)<br />
{<br />
//strip out <override> and </override><br />
<br />
ind=llSubStringIndex(llList2String(AIMList,i),"<override>");<br />
string1=llDeleteSubString(llList2String(AIMList,i),ind,ind+9);<br />
ind2=llSubStringIndex(string1,"</override>");<br />
string override_string=llDeleteSubString(string1,ind2,ind2+10);//this now represents string to match to message<br />
if(llSubStringIndex(message,override_string)!=-1)<br />
{<br />
<br />
reply_index=i;<br />
}<br />
} <br />
<br />
<br />
//find clusters/cluster2 in AIMList entry<br />
if(llSubStringIndex(llList2String(AIMList,i),"<pattern>")!=-1)<br />
{<br />
//strip out <pattern> and </pattern> from every line<br />
ind=llSubStringIndex(llList2String(AIMList,i),"<pattern>");<br />
string1=llDeleteSubString(llList2String(AIMList,i),ind,ind+8);<br />
ind2=llSubStringIndex(string1,"</pattern>");<br />
string unparsed_clusters_string=llDeleteSubString(string1,ind2,ind2+9);//this now represents string to match to message<br />
if(llSubStringIndex(unparsed_clusters_string,"*")!=-1)// && llSubStringIndex(unparsed_clusters_string,"#")==-1) //parse only lines using wildcard this way. non-wildcard parse follows<br />
{<br />
unparsed_clusters=llParseString2List(unparsed_clusters_string,["*"],[]); //break into 2 clusters, before * and after *<br />
<br />
<br />
<br />
lenclust=llGetListLength(unparsed_clusters);<br />
//unparsed_clusters=llDeleteSubList(unparsed_clusters,lenclust,lenclust);//what does this do? <br />
clusters=llList2List(unparsed_clusters,0,0); //Before * cluster <br />
cluster2=llList2List(unparsed_clusters,1,1);//after * cluster<br />
if(llSubStringIndex(unparsed_clusters_string,"*")==0)<br />
{<br />
cluster2=clusters;<br />
clusters=[];<br />
}<br />
cl=llParseString2List( (string) clusters,[" "],[]); //breaks out individual words in clusters<br />
cl2=llParseString2List( (string) cluster2,[" "],[]); //breaks out individual words in cluster2<br />
msglist=llParseString2List(message,[" "],[]); //breaks up input message into list of individual words. <br />
if(cl2==[])<br />
cl2=["asdfasfads"]; //insert unmatcheable value into cl2<br />
if(cl==[]) <br />
cl=["hgsjgh"];<br />
<br />
//Case of cluster *<br />
if(llListFindList(msglist,cl)!=-1 && llListFindList(msglist,cl2)==-1)<br />
{<br />
<br />
begin =llListFindList(msglist,cl); //find cl in msglist<br />
end=llGetListLength(cl);<br />
end--;<br />
tailmsglist=llDeleteSubList(msglist,begin,begin+end); //return only * and post * words<br />
<br />
starindex=llListFindList(msglist,tailmsglist); //locates *<br />
end2=llGetListLength(msglist);<br />
end2--; <br />
//if(end>=0 && begin>=0 && starindex >=0 && end2>=0) //so no negative indexes<br />
// newmsg=llDumpList2String(llListReplaceList(msglist,["*"],starindex,starindex+end2)," "); //replaces phrase with * in message<br />
//what to replace * with in reply<br />
starlist=llList2List(msglist,starindex,starindex+end2);<br />
<br />
//check similarity of matched pattern with message string<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)==cl+"*")<br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," "); <br />
}<br />
}<br />
<br />
//Case of * cluster2<br />
if(llListFindList(msglist,cl)==-1 && llListFindList(msglist,cl2)!=-1)<br />
{ <br />
begin=llListFindList(msglist,cl2);<br />
end=llGetListLength(cl2);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin, begin+end);<br />
starindex=llListFindList(msglist,headmsglist);<br />
end2=llGetListLength(headmsglist);<br />
end2--;<br />
//if(end>=0 && begin >=0 && starindex>=0 && end2>=0)<br />
// new<br />
starlist=llList2List(msglist, starindex, starindex+end2);<br />
starstring=llDumpList2String(starlist," ");<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)=="*"+cl2)<br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
<br />
}<br />
}<br />
<br />
//Case of clusters * cluster2<br />
if(llListFindList(msglist,cl)!=-1 && llListFindList(msglist,cl2)!=-1)<br />
{<br />
//first delete clusters from message<br />
<br />
begin=llListFindList(msglist, cl);<br />
end=llGetListLength(cl);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin,begin+end);<br />
<br />
//then delete cluster2 from tailmsglist<br />
begina =llListFindList(headmsglist, cl2);<br />
enda=llGetListLength(cl2);<br />
enda--;<br />
starlist=llDeleteSubList(headmsglist,begina,begina+enda);<br />
starindex=llListFindList(msglist,starlist);<br />
end2=llGetListLength(starlist);<br />
end2--;<br />
// starstring=llDumpList2String(starlist," ");<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)==cl+"*"+cl2 ) <br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
}<br />
}<br />
//case of cluster * cluster_a # cluster_b<br />
if(llSubStringIndex(unparsed_clusters_string,"#")!=-1)<br />
{<br />
////first delete clusters from message<br />
<br />
begin=llListFindList(msglist, cl);<br />
end=llGetListLength(cl);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin,begin+end);<br />
prestarlist=llList2List(msglist,begin,begin+end);<br />
//parse cluster2 into cluster_a and cluster_b<br />
startopoundlist=llParseString2List((string) cluster2, ["#"],[]);<br />
cluster_a=llList2List(startopoundlist,0,0);<br />
list cl_a=llParseString2List( (string) cluster_a,[" "],[]);<br />
//then delete cl_a from tailmsglist<br />
<br />
begina =llListFindList(headmsglist, cl_a);<br />
enda=llGetListLength(cl_a);<br />
enda--;<br />
<br />
<br />
//replace starlist in msglist first;<br />
integer endb=llGetListLength(headmsglist);<br />
starlist=llDeleteSubList(headmsglist,begina,endb--);<br />
starindex=llListFindList(msglist,starlist);<br />
end2=llGetListLength(starlist);<br />
end2--;<br />
//newmsglist=llListReplaceList(tailmsglist,["*"],starindex,starindex+end2);<br />
if(llGetListLength(startopoundlist)>1)<br />
{<br />
cluster_b=llList2List(startopoundlist,1,1);<br />
cl_b=llParseString2List( (string) cluster_b,[" "],[]);<br />
//find index of cl_b in msglist<br />
integer clbstart=llListFindList(headmsglist,llParseString2List((string) llList2List(startopoundlist,1,1),[" "],[])); //delete all but this<br />
integer lenmsglist=llGetListLength(headmsglist);<br />
poundlist=llDeleteSubList(headmsglist,clbstart,lenmsglist--); <br />
enda=llGetListLength(llParseString2List( (string) llList2List(startopoundlist,0,0),[" "],[]));<br />
poundlist=llDeleteSubList(poundlist,0,enda--) ;<br />
}<br />
<br />
//integer endb=llGetListLength(headmsglist);<br />
// starlist=llDeleteSubList(headmsglist,begina,endb--);<br />
<br />
<br />
starindex=llListFindList(msglist,starlist);<br />
<br />
// <br />
integer starlength=llGetListLength(starlist);<br />
starlength--;<br />
newmsglist=llListReplaceList(msglist,["*"],starindex,starindex+starlength--);<br />
integer poundindex=llListFindList(newmsglist,poundlist);<br />
integer poundlength=llGetListLength(poundlist);<br />
poundlength--;<br />
newmsglist=llListReplaceList(newmsglist,["#"],poundindex,poundindex+poundlength--);<br />
if(newmsglist==cl+["*"]+cl_a+["#"]+cl_b) <br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
poundstring=llDumpList2String(poundlist," ");<br />
}<br />
<br />
}<br />
}<br />
else<br />
{<br />
if(unparsed_clusters_string==message)<br />
reply_index=i;<br />
}<br />
}<br />
<br />
i++;<br />
<br />
}<br />
<br />
if(reply_index!=-1) //if a match exists<br />
{ <br />
if(llSubStringIndex(llList2String(AIMList,reply_index+1),"<channel>")!=-1)<br />
{<br />
ind=llSubStringIndex(llList2String(AIMList,reply_index+1),"<channel>");<br />
string1=llDeleteSubString(llList2String(AIMList,reply_index+1),ind,ind+8);<br />
ind2=llSubStringIndex(string1,"</channel>");<br />
string chat_channel_string=llDeleteSubString(string1,ind2,ind2+9); <br />
chat_channel=(integer) chat_channel_string;<br />
<br />
}<br />
unparsed_reply=llList2String(REPLYList, reply_index);<br />
end_tag=llSubStringIndex(unparsed_reply,"</template>");<br />
end_tag--;<br />
parsed_reply=llGetSubString(unparsed_reply,10,end_tag--); //from end of <template> to </template><br />
if(llSubStringIndex(parsed_reply, "<star/>")==-1)<br />
{<br />
if(llSubStringIndex(parsed_reply,"<srai")==-1)<br />
{<br />
llSay(chat_channel,parsed_reply);<br />
<br />
reply_index=0;<br />
}<br />
else<br />
{<br />
error_cond=-1;<br />
integer lenp=llStringLength(parsed_reply); <br />
integer termin=lenp--;<br />
termin--;termin--;termin--;termin--;termin--;termin--;termin--;termin--;<br />
// integer starindex2=llSubStringIndex(parsed_reply,"<star/>");<br />
// starindex2--;<br />
//if(starindex2!=-1)<br />
//{<br />
// parsed_reply=llGetSubString(parsed_reply,6,starindex) +" " +starstring;<br />
//}<br />
//else<br />
//{<br />
<br />
newmessage=llGetSubString(parsed_reply,6,termin);<br />
// }<br />
}<br />
}<br />
else // if <star/> expression exists, insert antecedant<br />
{<br />
//if <pound/> expression exists<br />
if(llSubStringIndex(parsed_reply,"<poun")!=-1)<br />
{<br />
temp_reply_list=llParseString2List(parsed_reply,[" "],[]); <br />
s_ind=llListFindList(temp_reply_list,["<pound/>"]);<br />
new_reply_list=llListReplaceList(temp_reply_list,[poundstring],s_ind,s_ind);<br />
parsed_reply=llDumpList2String(new_reply_list," ");<br />
llSay(0,(string)new_reply_list);<br />
<br />
}<br />
//else new_reply_list=llParseString2List(parsed_reply,[" "],[]);<br />
if(llSubStringIndex(parsed_reply,"<srai")==-1)<br />
{<br />
temp_reply_list=llParseString2List(parsed_reply,[" "],[]); <br />
integer s_ind2=llListFindList(temp_reply_list,["<star/>"]);<br />
temp_reply_list=llListReplaceList(temp_reply_list,[starstring],s_ind2,s_ind2);<br />
<br />
parsed_reply=llDumpList2String(temp_reply_list," ");<br />
llSay(chat_channel,parsed_reply);<br />
<br />
reply_index=0;<br />
}<br />
else <br />
{ <br />
//strip out <srai> tags<br />
integer srai_ind1=llSubStringIndex(parsed_reply,"<srai>");<br />
integer srai_ind2=llSubStringIndex(parsed_reply,"</srai>");<br />
//parsed_reply=llDeleteSubString(parsed_reply,srai_ind1,srai_ind1+5);<br />
<br />
parsed_reply=llGetSubString(parsed_reply,srai_ind1+6,srai_ind2-=1);<br />
//if pound expression exists<br />
if(llSubStringIndex(parsed_reply,"<poun")!=-1)<br />
{<br />
error_cond=-1; <br />
integer lenp=llStringLength(parsed_reply);<br />
integer termin=lenp--;<br />
integer poundindex2=llSubStringIndex(parsed_reply,"<pound/>");<br />
<br />
poundindex2--;<br />
if(poundindex2!=-1)<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,poundindex2) +poundstring;<br />
parsed_reply=llDeleteSubString(parsed_reply,poundindex2,poundindex2+8);<br />
parsed_reply=llInsertString(parsed_reply,poundindex,poundstring);<br />
//use llDeleteSubString followed by llInsertString<br />
}<br />
else<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,termin);<br />
<br />
}<br />
<br />
}<br />
error_cond=-1; <br />
<br />
integer lenp=llStringLength(parsed_reply);<br />
integer termin=lenp--;<br />
integer starindex2=llSubStringIndex(parsed_reply,"<star/>");<br />
starindex2--;<br />
if(starindex2!=-1)<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,starindex2) +starstring;<br />
parsed_reply=llDeleteSubString(parsed_reply,starindex2,starindex2+8);<br />
parsed_reply=llInsertString(parsed_reply,starindex,starstring);<br />
//use llDeleteSubString followed by llInsertString<br />
<br />
}<br />
else<br />
{<br />
newmessage=llGetSubString(parsed_reply,6,termin);<br />
<br />
}<br />
<br />
}<br />
<br />
}<br />
}<br />
else<br />
{<br />
llSay(0,"I'm afraid I don't understand what you said...yet");<br />
//email message to some address dedicated to receiving unmatched patterns. Uncomment line after inserting correct address<br />
//llEmail(address@whatever.com, "LindenAIML: New Template Needed", "no match for: " +message); // send email to self<br />
}<br />
return error_cond;<br />
}<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{<br />
llSetText("LindenAIML Concierge", <1,1,1>, 1.0);<br />
gQueryID=llGetNotecardLine(gName,gLine);//request first line<br />
gLine++; //increase line count<br />
}<br />
<br />
dataserver(key query_id,string data)<br />
{<br />
if(query_id==gQueryID)<br />
{ <br />
if(data!=EOF)<br />
{<br />
if( llGetSubString(data,0,3)=="<pat" || llGetSubString(data,0,3)=="<ove" || llGetSubString(data,0,3)=="<cha")<br />
{<br />
if(gLine==0) //for now ignore all but pattern or template lines<br />
{<br />
AIMList=(list) [data];<br />
} <br />
else<br />
{<br />
AIMList=AIMList + [data];<br />
}<br />
}<br />
if(llGetSubString(data,0,3)=="<tem" || llGetSubString(data,0,3)=="<cha" )<br />
{<br />
if(gLine==0) //for now ignore all but pattern or template lines <br />
{<br />
REPLYList=(list) [data];<br />
} <br />
else<br />
{<br />
REPLYList=REPLYList + [data];<br />
<br />
}<br />
<br />
}<br />
}<br />
gQueryID=llGetNotecardLine(gName,gLine); //request next line<br />
gLine++; <br />
}<br />
}<br />
<br />
touch_start(integer total_number)<br />
{<br />
<br />
<br />
if(touched==0)<br />
{<br />
handle=llListen(0,"",llGetOwner(),"");<br />
llSay(0,"AIML on");<br />
llGiveInventory(llDetectedKey(0), "LindenAIML");<br />
llGiveInventory(llDetectedKey(0), "LAIMLDocs");<br />
touched++;<br />
}<br />
else<br />
{<br />
llListenRemove(handle);<br />
llSay(0,"AIML off");<br />
touched=0;<br />
} <br />
<br />
}<br />
<br />
listen(integer channel, string name, key id, string msg)<br />
{<br />
<br />
integer error_cond=myParse(msg); <br />
if(error_cond==-1)<br />
{<br />
//message=newmessage;<br />
<br />
myParse(newmessage);<br />
}<br />
} <br />
}<br />
</source><br />
<br />
In addition to the LindenAIML interpreter code above, one also needs a “dialogue template” written in<br />
LindenAIML designed to coordinate responses to queries made on Second Life chat.<br />
<br />
The text below is intended to be incorporated as a notecard in an object containing the interpreter. This file, referred to as "filename" in the above code, contains the AIML tagged text to be used as a script for the interpreter. The syntax of LindenAIML is strict, as will be outlined below.<br />
<br />
<category><br />
<pattern>How are you *</pattern><br />
<template><star/> is fine</template><br />
</category><br />
<category><br />
<pattern>Are you well * bot</pattern><br />
<template>This <star/> bot is great</template><br />
</category><br />
<category><br />
<pattern>Who is *</pattern><br />
<template>I don't know, who is <star/></template><br />
</category><br />
<category><br />
<override>fish</override><br />
<template>I hate fish</template><br />
</category><br />
<category><br />
<pattern>Are there too many * in this sim</pattern><br />
<template>I don't know much about <star/></template><br />
</category><br />
<category><br />
<pattern>Are you OK * bot</pattern><br />
<template><srai>Are you well <star/> bot</srai></template><br />
</category><br />
<category><br />
<pattern>Reply on channel 1</pattern><br />
<template>OK</template><br />
<channel>1</channel><br />
</category><br />
<pattern>The * in spain falls mainly # the plain</pattern><br />
<template>That confounded <star/> falls mainly <pound/> that blasted plain</template><br />
</category><br />
<br />
A brief explication of the tags. As of this writing, the <category> tag is not used. In the future it will contain flags about topic and such like. But right now it's simply included to keep the LindenAIML file looking somewhat familiar to AIML users.<br />
<br />
The <pattern> tags contain patterns to match user utterances.<br />
The <template> tags contain hypothetical replies to the patterns.<br />
The <channel> tag (not included in every entry contained in <category></category> pair) allows the user to determin what channel the reply will occur on. So the bot can issue commands to other devices listening on those channels.<br />
<br />
<override> represents a special case of <pattern>. In the example, if the user says anything that contains the word "fish", the reply will be that in the <template></template> tags immediately following the <override></override> pair.<br />
<br />
<srai></srai> is the "syntactic reduction" tagpair. If a pattern produces a template with syntactic reduction tags enclosing the response, that responses is fed to the algorithm as a new user message to parse. The upshot of this: Patterns followed by <srai> tags are regarded as equivalent to the text contained in the <srai> tagpair, which should be defined elsewhere in the file (and by convention, previously in the file). Too many of these can slow operation considerably. Be warned.<br />
<br />
the <star/> tag is an isolated tag and represents the insertion point for phrases denoted by the wildcard "*" in the pattern to match. So If I say: "I hate you bot", and the pattern to match is "I * you bot", the template reply might be "Well, I <star/> you too.", resulting in a reply: "Well, I hate you too."<br />
<br />
A second wildcard has been implemented, using the “#” character. As with “*”, the “#” character will commonly replace the <pound/> tag in the reply string. As of this writing<br />
the second wildcard only processes patterns of the format "string1 * string2 # string3". Updates to LindenAIML will also allow the processing of patterns such as "* string #".<br />
<br />
Beware punctuation following <star/> or <pound/> tags. I have not, as yet, integrated that kind of punctuation into the parsing procedures. However, end of utterance punctuation is stripped from the user message at this point, so it is not necessary to include punctuation at the end of patterns.<br />
<br />
It is important to note that LindenAIML is sensitive to the format of the AIML file. No extra spaces between tags, and line-format should be as above. For example, if you put a space between the <pattern> tag and the first word of the actual pattern, you run the risk of confusing the interpreter. Also, tags must be lower case at this point. All tagsets except the <category></category> must be on the same line of text. In future versions, we hope to make LindenAIML more flexible sytlistically.<br />
<br />
-Azrael Baphomet and Luciftias Neurocam<br />
--copied from [http://lslwiki.digiworldz.com/lslwiki/wakka.php?wakka=LibraryLindenAIML] for the Linden Script Library.<br />
Visit my LSL wiki page for my library of scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/LindenAIML&diff=1209921User:Toady Nakamura/LindenAIML2021-03-03T19:55:28Z<p>Toady Nakamura: saved from an apparently 404 website by Toady.</p>
<hr />
<div>LindenAIML is inspired by Richard Wallace's AIML (artificial intelligence markup language). AIML utilizes the fact that humans, in conversation, often return to the same patterns of speech again and again, varying the words that determine the sentences reference, while keeping the mechanical structures largely similar. AIML replaces these variable portions of utterances with wildcards and attempts to match patterns in speech based on the invariant portions of utterances. For more information, read about ALICE.<br />
True AIML is an XML compliant language, and resembles HTML more than anything else. LindenAIML, while not XML compliant at this writing, imports most of the more commonly used features of AIML while supplementing it with features created specifically for the Second Life platform.<br />
<br />
The basic code for the LindenAIML interpreter is as follows:<br />
<br />
<source lang="lsl2"><br />
//The following code was generated by Luciftias Neurocam and Azrael Baphomet.<br />
//It is freely distributable under the terms of the GNU public license.<br />
//Please report significant mods to either Azrael or Luciftias. Thank you.<br />
<br />
<br />
string gName="filename";<br />
key gQueryID;<br />
list AIMList;<br />
list REPLYList;<br />
string data; <br />
string newmessage;<br />
integer gLine;<br />
integer handle;<br />
integer touched=0;<br />
<br />
integer myParse(string message) <br />
{<br />
integer begin; //index of message string marking beginning of matched pattern<br />
integer begin2; <br />
integer begina; //as above<br />
integer chat_channel=0;<br />
integer check_line; //no longer implemented<br />
integer end; //length of matched pattern, so ending index actually begin+end-1<br />
integer end_tag;<br />
integer end2;<br />
integer end3;<br />
integer enda;<br />
integer error_cond=0; //use later<br />
integer i=0; //loop (line) number<br />
integer ind;<br />
integer ind2;<br />
integer j;<br />
integer lenaimlist; //length of AIMList<br />
integer lenclust;<br />
integer poundindex;<br />
integer reply_index=-1;<br />
integer s_ind;<br />
integer starindex; //beginning index of *ed expression in message<br />
list cl; //individual words in clusters parsed to individual list entries<br />
list cl_a;<br />
list cl_b;<br />
list cl2; //individual words in cluster2 blah blah blah<br />
list cluster_a;<br />
list cluster_b;<br />
list cluster2;//cluster of post * words<br />
list clusters; //first cluster of pre * words<br />
list headmsglist;<br />
list msglist; //string message as parsed to list, separated by " "<br />
list new_reply_list;<br />
list newmsglist;<br />
list poundlist;<br />
list prestarlist;<br />
list starlist;<br />
list startopoundlist; //grabs text between star and pound<br />
list tailmsglist; <br />
list temp_reply_list;<br />
list unparsed_clusters;<br />
string last_message; //not used yet<br />
string newmsg;<br />
string parsed_reply;<br />
string poundstring;<br />
string resp_line;<br />
string starstring; //string corresponding to *ed characters<br />
string string1;<br />
string tempmessage="";<br />
string unparsed_clusters_string;<br />
string unparsed_reply;<br />
<br />
//begin actual program<br />
integer punc_index=llStringLength(message);<br />
punc_index--;<br />
if(llGetSubString(message,punc_index,punc_index)=="." || llGetSubString(message,punc_index,punc_index)=="!" || llGetSubString(message,punc_index,punc_index)=="?")<br />
{<br />
message=llDeleteSubString(message,punc_index,punc_index);<br />
}<br />
lenaimlist=llGetListLength(AIMList);<br />
reply_index=-1;<br />
while(reply_index==-1 && i< lenaimlist)//for(i=0;i<lenaimlist;i++)<br />
{<br />
clusters=[]; <br />
cluster2=[];<br />
cl=[];<br />
cl2=[];<br />
//override loop: if this string occurs anywhere in input, ignore all other parsing and respond with template following override<br />
if(llSubStringIndex(llList2String(AIMList,i),"<override>")!=-1)<br />
{<br />
//strip out <override> and </override><br />
<br />
ind=llSubStringIndex(llList2String(AIMList,i),"<override>");<br />
string1=llDeleteSubString(llList2String(AIMList,i),ind,ind+9);<br />
ind2=llSubStringIndex(string1,"</override>");<br />
string override_string=llDeleteSubString(string1,ind2,ind2+10);//this now represents string to match to message<br />
if(llSubStringIndex(message,override_string)!=-1)<br />
{<br />
<br />
reply_index=i;<br />
}<br />
} <br />
<br />
<br />
//find clusters/cluster2 in AIMList entry<br />
if(llSubStringIndex(llList2String(AIMList,i),"<pattern>")!=-1)<br />
{<br />
//strip out <pattern> and </pattern> from every line<br />
ind=llSubStringIndex(llList2String(AIMList,i),"<pattern>");<br />
string1=llDeleteSubString(llList2String(AIMList,i),ind,ind+8);<br />
ind2=llSubStringIndex(string1,"</pattern>");<br />
string unparsed_clusters_string=llDeleteSubString(string1,ind2,ind2+9);//this now represents string to match to message<br />
if(llSubStringIndex(unparsed_clusters_string,"*")!=-1)// && llSubStringIndex(unparsed_clusters_string,"#")==-1) //parse only lines using wildcard this way. non-wildcard parse follows<br />
{<br />
unparsed_clusters=llParseString2List(unparsed_clusters_string,["*"],[]); //break into 2 clusters, before * and after *<br />
<br />
<br />
<br />
lenclust=llGetListLength(unparsed_clusters);<br />
//unparsed_clusters=llDeleteSubList(unparsed_clusters,lenclust,lenclust);//what does this do? <br />
clusters=llList2List(unparsed_clusters,0,0); //Before * cluster <br />
cluster2=llList2List(unparsed_clusters,1,1);//after * cluster<br />
if(llSubStringIndex(unparsed_clusters_string,"*")==0)<br />
{<br />
cluster2=clusters;<br />
clusters=[];<br />
}<br />
cl=llParseString2List( (string) clusters,[" "],[]); //breaks out individual words in clusters<br />
cl2=llParseString2List( (string) cluster2,[" "],[]); //breaks out individual words in cluster2<br />
msglist=llParseString2List(message,[" "],[]); //breaks up input message into list of individual words. <br />
if(cl2==[])<br />
cl2=["asdfasfads"]; //insert unmatcheable value into cl2<br />
if(cl==[]) <br />
cl=["hgsjgh"];<br />
<br />
//Case of cluster *<br />
if(llListFindList(msglist,cl)!=-1 && llListFindList(msglist,cl2)==-1)<br />
{<br />
<br />
begin =llListFindList(msglist,cl); //find cl in msglist<br />
end=llGetListLength(cl);<br />
end--;<br />
tailmsglist=llDeleteSubList(msglist,begin,begin+end); //return only * and post * words<br />
<br />
starindex=llListFindList(msglist,tailmsglist); //locates *<br />
end2=llGetListLength(msglist);<br />
end2--; <br />
//if(end>=0 && begin>=0 && starindex >=0 && end2>=0) //so no negative indexes<br />
// newmsg=llDumpList2String(llListReplaceList(msglist,["*"],starindex,starindex+end2)," "); //replaces phrase with * in message<br />
//what to replace * with in reply<br />
starlist=llList2List(msglist,starindex,starindex+end2);<br />
<br />
//check similarity of matched pattern with message string<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)==cl+"*")<br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," "); <br />
}<br />
}<br />
<br />
//Case of * cluster2<br />
if(llListFindList(msglist,cl)==-1 && llListFindList(msglist,cl2)!=-1)<br />
{ <br />
begin=llListFindList(msglist,cl2);<br />
end=llGetListLength(cl2);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin, begin+end);<br />
starindex=llListFindList(msglist,headmsglist);<br />
end2=llGetListLength(headmsglist);<br />
end2--;<br />
//if(end>=0 && begin >=0 && starindex>=0 && end2>=0)<br />
// new<br />
starlist=llList2List(msglist, starindex, starindex+end2);<br />
starstring=llDumpList2String(starlist," ");<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)=="*"+cl2)<br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
<br />
}<br />
}<br />
<br />
//Case of clusters * cluster2<br />
if(llListFindList(msglist,cl)!=-1 && llListFindList(msglist,cl2)!=-1)<br />
{<br />
//first delete clusters from message<br />
<br />
begin=llListFindList(msglist, cl);<br />
end=llGetListLength(cl);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin,begin+end);<br />
<br />
//then delete cluster2 from tailmsglist<br />
begina =llListFindList(headmsglist, cl2);<br />
enda=llGetListLength(cl2);<br />
enda--;<br />
starlist=llDeleteSubList(headmsglist,begina,begina+enda);<br />
starindex=llListFindList(msglist,starlist);<br />
end2=llGetListLength(starlist);<br />
end2--;<br />
// starstring=llDumpList2String(starlist," ");<br />
if(llListReplaceList(msglist,["*"],starindex,starindex+end2)==cl+"*"+cl2 ) <br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
}<br />
}<br />
//case of cluster * cluster_a # cluster_b<br />
if(llSubStringIndex(unparsed_clusters_string,"#")!=-1)<br />
{<br />
////first delete clusters from message<br />
<br />
begin=llListFindList(msglist, cl);<br />
end=llGetListLength(cl);<br />
end--;<br />
headmsglist=llDeleteSubList(msglist,begin,begin+end);<br />
prestarlist=llList2List(msglist,begin,begin+end);<br />
//parse cluster2 into cluster_a and cluster_b<br />
startopoundlist=llParseString2List((string) cluster2, ["#"],[]);<br />
cluster_a=llList2List(startopoundlist,0,0);<br />
list cl_a=llParseString2List( (string) cluster_a,[" "],[]);<br />
//then delete cl_a from tailmsglist<br />
<br />
begina =llListFindList(headmsglist, cl_a);<br />
enda=llGetListLength(cl_a);<br />
enda--;<br />
<br />
<br />
//replace starlist in msglist first;<br />
integer endb=llGetListLength(headmsglist);<br />
starlist=llDeleteSubList(headmsglist,begina,endb--);<br />
starindex=llListFindList(msglist,starlist);<br />
end2=llGetListLength(starlist);<br />
end2--;<br />
//newmsglist=llListReplaceList(tailmsglist,["*"],starindex,starindex+end2);<br />
if(llGetListLength(startopoundlist)>1)<br />
{<br />
cluster_b=llList2List(startopoundlist,1,1);<br />
cl_b=llParseString2List( (string) cluster_b,[" "],[]);<br />
//find index of cl_b in msglist<br />
integer clbstart=llListFindList(headmsglist,llParseString2List((string) llList2List(startopoundlist,1,1),[" "],[])); //delete all but this<br />
integer lenmsglist=llGetListLength(headmsglist);<br />
poundlist=llDeleteSubList(headmsglist,clbstart,lenmsglist--); <br />
enda=llGetListLength(llParseString2List( (string) llList2List(startopoundlist,0,0),[" "],[]));<br />
poundlist=llDeleteSubList(poundlist,0,enda--) ;<br />
}<br />
<br />
//integer endb=llGetListLength(headmsglist);<br />
// starlist=llDeleteSubList(headmsglist,begina,endb--);<br />
<br />
<br />
starindex=llListFindList(msglist,starlist);<br />
<br />
// <br />
integer starlength=llGetListLength(starlist);<br />
starlength--;<br />
newmsglist=llListReplaceList(msglist,["*"],starindex,starindex+starlength--);<br />
integer poundindex=llListFindList(newmsglist,poundlist);<br />
integer poundlength=llGetListLength(poundlist);<br />
poundlength--;<br />
newmsglist=llListReplaceList(newmsglist,["#"],poundindex,poundindex+poundlength--);<br />
if(newmsglist==cl+["*"]+cl_a+["#"]+cl_b) <br />
{<br />
reply_index=i;<br />
starstring=llDumpList2String(starlist," ");<br />
poundstring=llDumpList2String(poundlist," ");<br />
}<br />
<br />
}<br />
}<br />
else<br />
{<br />
if(unparsed_clusters_string==message)<br />
reply_index=i;<br />
}<br />
}<br />
<br />
i++;<br />
<br />
}<br />
<br />
if(reply_index!=-1) //if a match exists<br />
{ <br />
if(llSubStringIndex(llList2String(AIMList,reply_index+1),"<channel>")!=-1)<br />
{<br />
ind=llSubStringIndex(llList2String(AIMList,reply_index+1),"<channel>");<br />
string1=llDeleteSubString(llList2String(AIMList,reply_index+1),ind,ind+8);<br />
ind2=llSubStringIndex(string1,"</channel>");<br />
string chat_channel_string=llDeleteSubString(string1,ind2,ind2+9); <br />
chat_channel=(integer) chat_channel_string;<br />
<br />
}<br />
unparsed_reply=llList2String(REPLYList, reply_index);<br />
end_tag=llSubStringIndex(unparsed_reply,"</template>");<br />
end_tag--;<br />
parsed_reply=llGetSubString(unparsed_reply,10,end_tag--); //from end of <template> to </template><br />
if(llSubStringIndex(parsed_reply, "<star/>")==-1)<br />
{<br />
if(llSubStringIndex(parsed_reply,"<srai")==-1)<br />
{<br />
llSay(chat_channel,parsed_reply);<br />
<br />
reply_index=0;<br />
}<br />
else<br />
{<br />
error_cond=-1;<br />
integer lenp=llStringLength(parsed_reply); <br />
integer termin=lenp--;<br />
termin--;termin--;termin--;termin--;termin--;termin--;termin--;termin--;<br />
// integer starindex2=llSubStringIndex(parsed_reply,"<star/>");<br />
// starindex2--;<br />
//if(starindex2!=-1)<br />
//{<br />
// parsed_reply=llGetSubString(parsed_reply,6,starindex) +" " +starstring;<br />
//}<br />
//else<br />
//{<br />
<br />
newmessage=llGetSubString(parsed_reply,6,termin);<br />
// }<br />
}<br />
}<br />
else // if <star/> expression exists, insert antecedant<br />
{<br />
//if <pound/> expression exists<br />
if(llSubStringIndex(parsed_reply,"<poun")!=-1)<br />
{<br />
temp_reply_list=llParseString2List(parsed_reply,[" "],[]); <br />
s_ind=llListFindList(temp_reply_list,["<pound/>"]);<br />
new_reply_list=llListReplaceList(temp_reply_list,[poundstring],s_ind,s_ind);<br />
parsed_reply=llDumpList2String(new_reply_list," ");<br />
llSay(0,(string)new_reply_list);<br />
<br />
}<br />
//else new_reply_list=llParseString2List(parsed_reply,[" "],[]);<br />
if(llSubStringIndex(parsed_reply,"<srai")==-1)<br />
{<br />
temp_reply_list=llParseString2List(parsed_reply,[" "],[]); <br />
integer s_ind2=llListFindList(temp_reply_list,["<star/>"]);<br />
temp_reply_list=llListReplaceList(temp_reply_list,[starstring],s_ind2,s_ind2);<br />
<br />
parsed_reply=llDumpList2String(temp_reply_list," ");<br />
llSay(chat_channel,parsed_reply);<br />
<br />
reply_index=0;<br />
}<br />
else <br />
{ <br />
//strip out <srai> tags<br />
integer srai_ind1=llSubStringIndex(parsed_reply,"<srai>");<br />
integer srai_ind2=llSubStringIndex(parsed_reply,"</srai>");<br />
//parsed_reply=llDeleteSubString(parsed_reply,srai_ind1,srai_ind1+5);<br />
<br />
parsed_reply=llGetSubString(parsed_reply,srai_ind1+6,srai_ind2-=1);<br />
//if pound expression exists<br />
if(llSubStringIndex(parsed_reply,"<poun")!=-1)<br />
{<br />
error_cond=-1; <br />
integer lenp=llStringLength(parsed_reply);<br />
integer termin=lenp--;<br />
integer poundindex2=llSubStringIndex(parsed_reply,"<pound/>");<br />
<br />
poundindex2--;<br />
if(poundindex2!=-1)<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,poundindex2) +poundstring;<br />
parsed_reply=llDeleteSubString(parsed_reply,poundindex2,poundindex2+8);<br />
parsed_reply=llInsertString(parsed_reply,poundindex,poundstring);<br />
//use llDeleteSubString followed by llInsertString<br />
}<br />
else<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,termin);<br />
<br />
}<br />
<br />
}<br />
error_cond=-1; <br />
<br />
integer lenp=llStringLength(parsed_reply);<br />
integer termin=lenp--;<br />
integer starindex2=llSubStringIndex(parsed_reply,"<star/>");<br />
starindex2--;<br />
if(starindex2!=-1)<br />
{<br />
parsed_reply=llGetSubString(parsed_reply,6,starindex2) +starstring;<br />
parsed_reply=llDeleteSubString(parsed_reply,starindex2,starindex2+8);<br />
parsed_reply=llInsertString(parsed_reply,starindex,starstring);<br />
//use llDeleteSubString followed by llInsertString<br />
<br />
}<br />
else<br />
{<br />
newmessage=llGetSubString(parsed_reply,6,termin);<br />
<br />
}<br />
<br />
}<br />
<br />
}<br />
}<br />
else<br />
{<br />
llSay(0,"I'm afraid I don't understand what you said...yet");<br />
//email message to some address dedicated to receiving unmatched patterns. Uncomment line after inserting correct address<br />
//llEmail(address@whatever.com, "LindenAIML: New Template Needed", "no match for: " +message); // send email to self<br />
}<br />
return error_cond;<br />
}<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{<br />
llSetText("LindenAIML Concierge", <1,1,1>, 1.0);<br />
gQueryID=llGetNotecardLine(gName,gLine);//request first line<br />
gLine++; //increase line count<br />
}<br />
<br />
dataserver(key query_id,string data)<br />
{<br />
if(query_id==gQueryID)<br />
{ <br />
if(data!=EOF)<br />
{<br />
if( llGetSubString(data,0,3)=="<pat" || llGetSubString(data,0,3)=="<ove" || llGetSubString(data,0,3)=="<cha")<br />
{<br />
if(gLine==0) //for now ignore all but pattern or template lines<br />
{<br />
AIMList=(list) [data];<br />
} <br />
else<br />
{<br />
AIMList=AIMList + [data];<br />
}<br />
}<br />
if(llGetSubString(data,0,3)=="<tem" || llGetSubString(data,0,3)=="<cha" )<br />
{<br />
if(gLine==0) //for now ignore all but pattern or template lines <br />
{<br />
REPLYList=(list) [data];<br />
} <br />
else<br />
{<br />
REPLYList=REPLYList + [data];<br />
<br />
}<br />
<br />
}<br />
}<br />
gQueryID=llGetNotecardLine(gName,gLine); //request next line<br />
gLine++; <br />
}<br />
}<br />
<br />
touch_start(integer total_number)<br />
{<br />
<br />
<br />
if(touched==0)<br />
{<br />
handle=llListen(0,"",llGetOwner(),"");<br />
llSay(0,"AIML on");<br />
llGiveInventory(llDetectedKey(0), "LindenAIML");<br />
llGiveInventory(llDetectedKey(0), "LAIMLDocs");<br />
touched++;<br />
}<br />
else<br />
{<br />
llListenRemove(handle);<br />
llSay(0,"AIML off");<br />
touched=0;<br />
} <br />
<br />
}<br />
<br />
listen(integer channel, string name, key id, string msg)<br />
{<br />
<br />
integer error_cond=myParse(msg); <br />
if(error_cond==-1)<br />
{<br />
//message=newmessage;<br />
<br />
myParse(newmessage);<br />
}<br />
} <br />
}<br />
</source><br />
<br />
In addition to the LindenAIML interpreter code above, one also needs a “dialogue template” written in<br />
LindenAIML designed to coordinate responses to queries made on Second Life chat.<br />
<br />
The text below is intended to be incorporated as a notecard in an object containing the interpreter. This file, referred to as "filename" in the above code, contains the AIML tagged text to be used as a script for the interpreter. The syntax of LindenAIML is strict, as will be outlined below.<br />
<br />
<category><br />
<pattern>How are you *</pattern><br />
<template><star/> is fine</template><br />
</category><br />
<category><br />
<pattern>Are you well * bot</pattern><br />
<template>This <star/> bot is great</template><br />
</category><br />
<category><br />
<pattern>Who is *</pattern><br />
<template>I don't know, who is <star/></template><br />
</category><br />
<category><br />
<override>fish</override><br />
<template>I hate fish</template><br />
</category><br />
<category><br />
<pattern>Are there too many * in this sim</pattern><br />
<template>I don't know much about <star/></template><br />
</category><br />
<category><br />
<pattern>Are you OK * bot</pattern><br />
<template><srai>Are you well <star/> bot</srai></template><br />
</category><br />
<category><br />
<pattern>Reply on channel 1</pattern><br />
<template>OK</template><br />
<channel>1</channel><br />
</category><br />
<pattern>The * in spain falls mainly # the plain</pattern><br />
<template>That confounded <star/> falls mainly <pound/> that blasted plain</template><br />
</category><br />
<br />
A brief explication of the tags. As of this writing, the <category> tag is not used. In the future it will contain flags about topic and such like. But right now it's simply included to keep the LindenAIML file looking somewhat familiar to AIML users.<br />
<br />
The <pattern> tags contain patterns to match user utterances.<br />
The <template> tags contain hypothetical replies to the patterns.<br />
The <channel> tag (not included in every entry contained in <category></category> pair) allows the user to determin what channel the reply will occur on. So the bot can issue commands to other devices listening on those channels.<br />
<br />
<override> represents a special case of <pattern>. In the example, if the user says anything that contains the word "fish", the reply will be that in the <template></template> tags immediately following the <override></override> pair.<br />
<br />
<srai></srai> is the "syntactic reduction" tagpair. If a pattern produces a template with syntactic reduction tags enclosing the response, that responses is fed to the algorithm as a new user message to parse. The upshot of this: Patterns followed by <srai> tags are regarded as equivalent to the text contained in the <srai> tagpair, which should be defined elsewhere in the file (and by convention, previously in the file). Too many of these can slow operation considerably. Be warned.<br />
<br />
the <star/> tag is an isolated tag and represents the insertion point for phrases denoted by the wildcard "*" in the pattern to match. So If I say: "I hate you bot", and the pattern to match is "I * you bot", the template reply might be "Well, I <star/> you too.", resulting in a reply: "Well, I hate you too."<br />
<br />
A second wildcard has been implemented, using the “#” character. As with “*”, the “#” character will commonly replace the <pound/> tag in the reply string. As of this writing<br />
the second wildcard only processes patterns of the format "string1 * string2 # string3". Updates to LindenAIML will also allow the processing of patterns such as "* string #".<br />
<br />
Beware punctuation following <star/> or <pound/> tags. I have not, as yet, integrated that kind of punctuation into the parsing procedures. However, end of utterance punctuation is stripped from the user message at this point, so it is not necessary to include punctuation at the end of patterns.<br />
<br />
It is important to note that LindenAIML is sensitive to the format of the AIML file. No extra spaces between tags, and line-format should be as above. For example, if you put a space between the <pattern> tag and the first word of the actual pattern, you run the risk of confusing the interpreter. Also, tags must be lower case at this point. All tagsets except the <category></category> must be on the same line of text. In future versions, we hope to make LindenAIML more flexible sytlistically.<br />
<br />
-Azrael Baphomet and Luciftias Neurocam<br />
--saved from an apparently 404 website by Toady.<br />
Visit my LSL wiki page for my library of scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/ELIZA_chatbot&diff=1209920User:Toady Nakamura/ELIZA chatbot2021-03-03T19:53:34Z<p>Toady Nakamura: create ELIZA chatbot here because original source is linked to 404 pages and it shouldn't get lost</p>
<hr />
<div>'''Eliza Chatbot'''<br />
''Sources & links at bottom of page! <br />
About ELIZA<br />
<br />
ELIZA is a famous 1966 computer program by Joseph Weizenbaum<br />
ELIZA is a parody of a Rogerian therapist<br />
ELIZA rephrases many of the patient's statements as questions and posing them to the patient.<br />
<br />
Transcript of a sample conversation:<br />
<br />
You: hi<br />
Eliza Doolittle: how do you do--please state your problem.<br />
You: i don't have a problem<br />
Eliza Doolittle: does that trouble you?<br />
You: no<br />
Eliza Doolittle: you are being a bit negative.<br />
You: does that trouble you?<br />
Eliza Doolittle: we were discussing you-- not me.<br />
You: you have the problem.<br />
Eliza Doolittle: oh, i have the problem<br />
You: yes<br />
Eliza Doolittle: i see.<br />
<br />
<br />
Chatbot.Eliza.lsl<br />
<br />
<source lang="lsl2"><br />
// ELIZA is a famous 1966 computer program by Joseph Weizenbaum<br />
// ELIZA is a parody of a Rogerian therapist<br />
// ELIZA rephrases many of the patient's statements as questions and posing them to the patient.<br />
<br />
// This LSL version was originally ported by Dedric Mauriac<br />
// This LSL version is a port from a BASIC implementation written by John Schugg in January 1985.<br />
<br />
// Data Setup:<br />
// Keywords and patterns are contained in a seperate notecard<br />
// a keyword set appears on a line delimited with semi-colon and prefixed with number of responses<br />
// each response is written on its own line<br />
// if more then one response follows a set of keywords, a random response will be chosen<br />
// the last keyword in the notecard will always be used for responses that are not understood<br />
// blank lines should only appear before keywords or after the last response.<br />
// blank lines are optional and only used for easier management of data<br />
<br />
// how long to wait before responding and listening for next user input<br />
float delay = 7.5; <br />
<br />
// name of notecard containing patterns and responses<br />
string replyNote = "Chatbot.Eliza.txt";<br />
<br />
// stated when end-user repeats themselves<br />
string repeatReply = "please do not repeat yourself";<br />
<br />
// greeting<br />
string introduction = "Have any problems? Let me help you.";<br />
<br />
// don't listen to objects?<br />
integer ignoreObjects = TRUE;<br />
<br />
list keywords; // recognized keywords<br />
list matchStart; // start position in notecard for responses to each keyword<br />
list matchCount; // number of responses for each keyword<br />
integer lastLine;<br />
<br />
// number of lines in reply notecard<br />
integer replyLines;<br />
<br />
// id of request for notecard line count<br />
key replyCountId;<br />
<br />
// current line number being requested from notecard<br />
integer replyLine;<br />
<br />
// id of request for text in notecard for initialization<br />
key replyLineId;<br />
<br />
// characters recognized from user input<br />
string recognized = "abcdefghijklmnopqrstuvwxyz ";<br />
<br />
// id of listener for user input<br />
integer listener;<br />
<br />
// id of request for text in notecard as a response to input<br />
key responseId;<br />
<br />
string said; // what the user said<br />
string matched; // keyword/phrase the program understood<br />
<br />
integer processing = FALSE; // state if program is still processing last input<br />
<br />
string say; // response to user input<br />
<br />
initialize()<br />
{<br />
lastLine = -1;<br />
replyLine = 0;<br />
replyLines = -1;<br />
showProgress();<br />
keywords = [];<br />
matchCount = [];<br />
matchStart = [];<br />
replyCountId = llGetNumberOfNotecardLines(replyNote);<br />
}<br />
<br />
readReplies()<br />
{<br />
// at end of notecard?<br />
if(replyLine >= replyLines)<br />
{<br />
startSession();<br />
}<br />
else<br />
{ <br />
showProgress(); <br />
replyLineId = llGetNotecardLine(replyNote, replyLine++); // read next line<br />
}<br />
}<br />
<br />
initializeReply(string data)<br />
{<br />
data = llToLower(data);<br />
<br />
// is this a pattern?<br />
if(llSubStringIndex(data, ";") != -1)<br />
{<br />
list patterns = llParseString2List(data, [";"], []);<br />
integer count = llList2Integer(patterns, 0);<br />
keywords += llDeleteSubList(patterns, 0, 0);<br />
replyLine++;<br />
setMatchStart();<br />
setMatchLength(count);<br />
replyLine += count;<br />
}<br />
<br />
readReplies();<br />
}<br />
<br />
processMessage(string message)<br />
{<br />
// don't process if we are still working on the last message<br />
if(processing) return;<br />
processing = TRUE;<br />
<br />
message = formatMessage(message);<br />
<br />
// do not bother with repeat input<br />
if(said == message)<br />
{<br />
say = repeatReply;<br />
llSetTimerEvent(delay);<br />
return;<br />
}<br />
<br />
// remember what user said last<br />
said = message;<br />
<br />
// iterate through keywords<br />
integer n = llGetListLength(keywords);<br />
integer i;<br />
for(i = 0; i < n; i++)<br />
{<br />
// pad keyword with spaces<br />
string keyword = " " + llList2String(keywords, i) + " ";<br />
<br />
// if keyword in user-input, respond to it.<br />
if(llSubStringIndex(message, keyword) != -1)<br />
{<br />
respondTo(i);<br />
return;<br />
}<br />
}<br />
<br />
// since keyword not found, response with last keywords replies (not understood)<br />
respondTo(n - 1);<br />
}<br />
<br />
string formatMessage(string message)<br />
{ <br />
message = llToLower(message); // remove punctuation and change everything to lowercase<br />
string format = " ";<br />
integer i;<br />
integer n = llStringLength(message);<br />
<br />
for(i = 0; i < n; i++)<br />
{<br />
string char = llGetSubString(message, i, i);<br />
if(llSubStringIndex(recognized, char) != -1) format += char;<br />
}<br />
<br />
return format + " ";<br />
}<br />
<br />
respondTo(integer keywordIndex)<br />
{<br />
// determine what keyword to respond to<br />
matched = llList2String(keywords, keywordIndex);<br />
<br />
// determine what to respond with<br />
integer start = llList2Integer(matchStart, keywordIndex);<br />
integer count = llList2Integer(matchCount, keywordIndex);<br />
integer line = start + llFloor(llFrand(count));<br />
<br />
// prevent repeat response<br />
while(line == lastLine && count != 1)<br />
{<br />
line = start + llFloor(llFrand(count));<br />
}<br />
<br />
lastLine = line;<br />
<br />
// request text for chosen response<br />
responseId = llGetNotecardLine(replyNote, line);<br />
}<br />
<br />
string conjugateWord(string word)<br />
{<br />
// used to rephrase input into responses<br />
list conjugations = ["are", "am", <br />
"were", "was", <br />
"you", "i", <br />
"your", "my", <br />
"ive", "youve", <br />
"im", "youre", <br />
"you", "me"];<br />
<br />
// find word to replace<br />
integer i = llListFindList(conjugations, [word]);<br />
<br />
// not found<br />
if(i == -1) return word;<br />
<br />
// word found. opposites in pairs.<br />
if(i % 2 == 0) return llList2String(conjugations, i + 1);<br />
return llList2String(conjugations, i - 1);<br />
}<br />
<br />
string processConjugates()<br />
{<br />
// rephrase what user said after the matched keyword.<br />
<br />
integer i = llSubStringIndex(said, matched);<br />
string text = llGetSubString(said, i + llStringLength(matched), -1);<br />
list words = llParseString2List(text, [" "], []);<br />
text = "";<br />
<br />
integer n = llGetListLength(words);<br />
<br />
for(i = 0; i < n; i++)<br />
{<br />
text += " " + conjugateWord(llList2String(words, i));<br />
}<br />
<br />
return text;<br />
}<br />
<br />
processResponse(string message)<br />
{<br />
// format response<br />
message = llToLower(message);<br />
<br />
// if wildcard in response, rephrase what user said<br />
integer i = llSubStringIndex(message, "*");<br />
if(i != -1)<br />
{<br />
message = llDeleteSubString(message, i, i);<br />
message = llInsertString(message, i, processConjugates());<br />
}<br />
<br />
// prepare to respond<br />
say = message;<br />
llSetTimerEvent(delay);<br />
}<br />
<br />
showProgress()<br />
{<br />
// determine how much is done<br />
integer percent = (integer)(((float)replyLine / (float)replyLines) * 100);<br />
<br />
// build a text based progress bar - 59% [|||||......]<br />
string progress = (string)percent + "%\n[";<br />
integer i = 0;<br />
for(i = 0; i < 100; i+= 3)<br />
{<br />
if(i <= percent) progress += "|"; <br />
else progress += ".";<br />
}<br />
progress += "]";<br />
<br />
llSetText("Initializing\n" + progress, <1,1,1>, 1);<br />
}<br />
<br />
setMatchStart()<br />
{<br />
// set starting index for all keywords that do not yet have it set<br />
integer count = llGetListLength(keywords);<br />
integer i = llGetListLength(matchStart);<br />
for(; i < count; i++) matchStart += [replyLine - 1];<br />
}<br />
<br />
setMatchLength(integer length)<br />
{<br />
// determine number of replies for keyword set<br />
integer count = llGetListLength(keywords);<br />
integer i = llGetListLength(matchCount);<br />
for(; i < count; i++) matchCount += [length];<br />
}<br />
<br />
startSession()<br />
{<br />
// start listening<br />
llSetText("", ZERO_VECTOR, 0);<br />
if(listener != 0) llListenRemove(listener);<br />
listener = llListen(PUBLIC_CHANNEL, "", NULL_KEY, "");<br />
llSay(0, introduction);<br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
initialize();<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
initialize();<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if(change & CHANGED_INVENTORY) initialize();<br />
}<br />
<br />
dataserver(key queryId, string data) <br />
{<br />
if(queryId == replyCountId) // finding reply count<br />
{<br />
replyLines = (integer)data;<br />
readReplies();<br />
}<br />
else if(queryId == replyLineId) // initializing keywords/replies<br />
{<br />
initializeReply(data);<br />
}<br />
else if(queryId == responseId) // retrieving response template<br />
{<br />
processResponse(data);<br />
}<br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(!ignoreObjects && llGetOwnerKey(id) == id)<br />
{<br />
processMessage(message);<br />
}<br />
}<br />
<br />
touch_start(integer count)<br />
{<br />
llSay(0, introduction);<br />
}<br />
<br />
timer()<br />
{<br />
// say what we previously decided to say<br />
llSay(PUBLIC_CHANNEL, say);<br />
llSetTimerEvent(0);<br />
<br />
processing = FALSE; // listen for next input<br />
}<br />
}<br />
<br />
</source><br />
<br />
<br />
<br />
---- Make a notecard and put the following text into it for a sample!<br />
<br />
3;CAN YOU<br />
DON'T YOU BELIEVE THAT I CAN*<br />
PERHAPS YOU WOULD LIKE TO BE ABLE TO*<br />
YOU WANT ME TO BE ABLE TO*<br />
<br />
2;CAN I<br />
PERHAPS YOU DON'T WANT TO*<br />
DO YOU WANT TO BE ABLE TO*<br />
<br />
4;YOU ARE;YOURE<br />
WHAT MAKES YOU THINK I AM*<br />
DOES IT PLEASE YOU TO BELIEVE I AM*<br />
PERHAPS YOU WOULD LIKE TO BE*<br />
DO YOU SOMETIMES WISH YOU WERE*<br />
<br />
4;I DONT<br />
DON'T YOU REALLY*<br />
WHY DON'T YOU*<br />
DO YOU WISH TO BE ABLE TO*<br />
DOES THAT TROUBLE YOU?<br />
<br />
3;I FEEL<br />
TELL ME MORE ABOUT SUCH FEELINGS.<br />
DO YOU OFTEN FEEL*<br />
DO YOU ENJOY FEELING*<br />
<br />
3;WHY DONT YOU<br />
DO YOU REALLY BELIEVE I DON'T*<br />
PERHAPS IN GOOD TIME I WILL*<br />
DO YOU WANT ME TO*<br />
<br />
2;WHY CANT I<br />
DO YOU THINK YOU SHOULD BE ABLE TO*<br />
WHY CAN'T YOU*<br />
<br />
3;ARE YOU<br />
WHY ARE YOU INTERESTED IN WHETHER OR NOT I AM*<br />
WOULD YOU PREFER IF I WERE NOT*<br />
PERHAPS IN YOUR FANTASIES I AM*<br />
<br />
3;I CANT<br />
HOW DO YOU KNOW YOU CAN'T*<br />
HAVE YOU TRIED?<br />
PERHAPS YOU CAN NOW*<br />
<br />
4;I AM;IM<br />
DID YOU COME TO ME BECAUSE YOU ARE*<br />
HOW LONG HAVE YOU BEEN*<br />
DO YOU BELIEVE IT IS NORMAL TO BE*<br />
DO YOU ENJOY BEING*<br />
<br />
3;YOU<br />
WE WERE DISCUSSING YOU-- NOT ME.<br />
OH, I*<br />
YOU'RE NOT REALLY TALKING ABOUT ME, ARE YOU?<br />
<br />
5;I WANT<br />
WHY DO YOU WANT*<br />
WHAT IF YOU NEVER GOT*<br />
I SOMETIMES ALSO WANT*<br />
WHAT WOULD IT MEAN TO YOU IF YOU GOT*<br />
SUPPOSE YOU SOON GOT*<br />
<br />
9;WHAT;HOW;WHO;WHERE;WHEN;WHY<br />
WHY DO YOU ASK?<br />
DOES THAT QUESTION INTEREST YOU?<br />
WHAT ANSWER WOULD PLEASE YOU THE MOST?<br />
WHAT DO YOU THINK?<br />
ARE SUCH QUESTIONS ON YOUR MIND OFTEN?<br />
WHAT IS IT THAT YOU REALLY WANT TO KNOW?<br />
HAVE YOU ASKED ANYONE ELSE?<br />
HAVE YOU ASKED SUCH QUESTIONS BEFORE?<br />
WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?<br />
<br />
2;NAME<br />
NAMES DON'T INTEREST ME.<br />
I DON'T CARE ABOUT NAMES-- PLEASE GO ON.<br />
<br />
4;CAUSE<br />
IS THAT THE REAL REASON?<br />
DON'T ANY OTHER REASONS COME TO MIND?<br />
DOES THAT REASON EXPLAIN ANY THING ELSE?<br />
WHAT OTHER REASONS MIGHT THERE BE?<br />
<br />
4;SORRY<br />
PLEASE DON'T APOLOGIZE.<br />
APOLOGIES ARE NOT NECESSARY.<br />
WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?<br />
DON'T BE SO DEFENSIVE!<br />
<br />
4;DREAM<br />
WHAT DOES THAT DREAM SUGGEST TO YOU?<br />
DO YOU DREAM OFTEN?<br />
WHAT PERSONS APPEAR IN YOUR DREAMS?<br />
ARE YOU DISTURBED BY YOUR DREAMS?<br />
<br />
1;HELLO;HI<br />
HOW DO YOU DO--PLEASE STATE YOUR PROBLEM.<br />
<br />
5;MAYBE<br />
YOU DON'T SEEM QUITE CERTAIN.<br />
WHY THE UNCERTAIN TONE?<br />
CAN'T YOU BE MORE POSITIVE?<br />
YOU AREN'T SURE?<br />
DON'T YOU KNOW?<br />
<br />
5;NO<br />
ARE YOU SAYING NO JUST TO BE NEGATIVE?<br />
YOU ARE BEING A BIT NEGATIVE.<br />
WHY NOT?<br />
ARE YOU SURE?<br />
WHY NO?<br />
<br />
2;YOUR<br />
WHY ARE YOU CONCERNED ABOUT MY*<br />
WHAT ABOUT YOUR OWN*<br />
<br />
4;ALWAYS<br />
CAN YOU THINK OF A SPECIFIC EXAMPLE?<br />
WHEN?<br />
WHAT ARE YOU THINKING OF?<br />
REALLY, ALWAYS?<br />
<br />
3;THINK<br />
DO YOU REALLY THINK SO?<br />
BUT YOU ARE NOT SURE YOU*<br />
DO YOU DOUBT YOU*<br />
<br />
7;ALIKE<br />
IN WHAT WAY?<br />
WHAT RESEMBLANCE DO YOU SEE?<br />
WHAT DOES THE SIMILARITY SUGGEST TO YOU?<br />
WHAT OTHER CONNECTIONS DO YOU SEE?<br />
COULD THERE REALLY BE SOME CONNECTION?<br />
HOW?<br />
YOU SEEM QUITE POSITIVE.<br />
<br />
3;YES<br />
ARE YOU SURE?<br />
I SEE.<br />
I UNDERSTAND.<br />
<br />
6;FRIEND<br />
WHY DO YOU BRING UP THE TOPIC OF FRIENDS?<br />
DO YOUR FRIENDS WORRY YOU?<br />
DO YOUR FRIENDS PICK ON YOU?<br />
ARE YOU SURE YOU HAVE ANY FRIENDS?<br />
DO YOU IMPOSE ON YOUR FRIENDS?<br />
PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU?<br />
<br />
7;COMPUTER<br />
DO COMPUTERS WORRY YOU?<br />
ARE YOU TALKING ABOUT ME IN PARTICULAR?<br />
ARE YOU FRIGHTENED BY MACHINES?<br />
WHY DO YOU MENTION COMPUTERS?<br />
WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?<br />
DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?<br />
WHAT IS IT ABOUT MACHINES THAT WORRIES YOU?<br />
<br />
5;CAR<br />
OH, DO YOU LIKE CARS?<br />
MY FAVORITE CAR IS A LAMBORGINI COUNTACH. WHAT IS YOUR FAVORITE CAR?<br />
MY FAVORITE CAR COMPANY IS FERRARI. WHAT IS YOURS?<br />
DO YOU LIKE PORSCHES?<br />
DO YOU LIKE PORSCHE TURBO CARRERAS?<br />
<br />
6;NOKEYFOUND<br />
SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS?<br />
WHAT DOES THAT SUGGEST TO YOU?<br />
I SEE.<br />
I'M NOT SURE I UNDERSTAND YOU FULLY.<br />
COME COME ELUCIDATE YOUR THOUGHTS.<br />
CAN YOU ELABORATE ON THAT?<br />
<br />
---- This ends the notecard, be sure there are no blank lines at the end of your card!<br />
<br />
[https://www.chegg.com/homework-help/questions-and-answers/eliza-famous-1966-computer-program-written-joseph-weizenbaum-imitates-psychologist-specifi-q24553990 about ELIZA]<br />
[https://en.wikipedia.org/wiki/ELIZA Wikipedia ELIZA]<br />
[http://lslwiki.digiworldz.com/lslwiki/wakka.php?wakka=LibraryElizaChatbot Defunct Wiki.wakka source]<br />
<br />
Visit my LSL wiki page for my library of scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=LlSetClickAction&diff=1209919LlSetClickAction2021-03-03T19:47:28Z<p>Toady Nakamura: in tip jar, changed to llSetClickAction(CLICK_ACTION_PAY); since before it was to ACTION_BUY which is not right for tipjar.</p>
<hr />
<div>{{LSL_Function<br />
|inject-2={{Issues/VWR-640}}{{Issues/VWR-10829}}<br />
|func_id=333|func_sleep=0.0|func_energy=10.0<br />
|func=llSetClickAction<br />
|p1_type=integer|p1_subtype=click_action|p1_name=action|p1_desc=CLICK_ACTION_* flag<br />
|func_desc=Sets the action performed when a prim is clicked upon (aka [[click action]]).<br />
|func_footnote=When the cursor hovers over the prim, its image changes to reflect the action.<br />
|caveats= *When set in the root of an object the chosen CLICK_ACTION_* will be that for the children also even if they have their own [[llSetClickAction]] set (it will be over-ridden). However (in the case of [[touch]] for example) if the CLICK_ACTION_* is set in the root but not at all in the children (including not having [[touch]] [[event]] [[script]]s in them (this creates a default CLICK_ACTION_TOUCH)) the effect of the roots CLICK_ACTION_* is not ''seen'' but the CLICK_ACTION_* is ''used'' on clicking. To both use '''and see''' the correct cursor the CLICK_ACTION_* flags must match in the children and root.<br />
*If [[llSetClickAction]] is [[CLICK_ACTION_PAY]] then you must have a [[money]] event, or it will revert to [[CLICK_ACTION_NONE]].<br />
*While this function works or attached objects (click action can be changed), the configured click action of an attachment is ignored by the viewer. The viewer always behaves as though an attached object has [[CLICK_ACTION_TOUCH]] set.<br />
|examples={{{!}} width="100%" {{Prettytable}}<br />
{{!}}- {{Hl2}}<br />
! '''make sitting easier'''<br />
! '''make unpaking for next owner easier'''<br />
! '''make buying for customers easier'''<br />
{{!}}- valign="bottom"<br />
{{!!}}<source lang="lsl2"><br />
default<br />
{<br />
state_entry()<br />
{<br />
llSetClickAction(CLICK_ACTION_SIT);<br />
llRemoveInventory(llGetScriptName());<br />
}<br />
}<br />
</source><br />
{{!!}}<br />
<source lang="lsl2"><br />
default<br />
{<br />
state_entry()<br />
{<br />
llSetClickAction(CLICK_ACTION_OPEN);<br />
llRemoveInventory(llGetScriptName());<br />
}<br />
}<br />
</source><br />
{{!!}}<br />
<source lang="lsl2"><br />
// remember you'll have to set a price<br />
// in the general tab of the edit window<br />
// for your object before using this script<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSetClickAction(CLICK_ACTION_BUY);<br />
llRemoveInventory(llGetScriptName());<br />
}<br />
}<br />
</source><br />
{{!}}}<br />
<source lang="lsl2"><br />
// simple tipjar<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSetClickAction(CLICK_ACTION_PAY);<br />
<br />
// enabled edit field to put own amount, all quick-pay-buttons hidden<br />
llSetPayPrice(PAY_DEFAULT, [PAY_HIDE, PAY_HIDE, PAY_HIDE, PAY_HIDE]);<br />
}<br />
<br />
money(key id, integer amount)<br />
{<br />
string name = llKey2Name(id);<br />
<br />
llInstantMessage(id, "Thank you for the tip, " + name + "!");<br />
}<br />
}<br />
</source><br />
<br />
<source lang="lsl2"><br />
//Sit Only with Permission<br />
<br />
list gAvWhitelist = ["953d10f1-44ce-462a-8bc1-f634333ee031","599dce91-a2b8-48c5-b96d-54965433022b"];<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSitTarget(<0.0,0.0,0.5>,ZERO_ROTATION);<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if(change & CHANGED_LINK)<br />
{<br />
list Properties = llGetObjectDetails(llGetKey(),[OBJECT_CLICK_ACTION]);<br />
integer Click = llList2Integer(Properties,0);<br />
key Av = llAvatarOnSitTarget();<br />
if ((Av != NULL_KEY) && (!Click))<br />
{<br />
llSay(0,"Please click first for permission to sit.");<br />
llUnSit(Av);<br />
}<br />
}<br />
}<br />
touch_start(integer total_number)<br />
{<br />
list Properties = llGetObjectDetails(llGetKey(),[OBJECT_CLICK_ACTION]);<br />
integer Click = llList2Integer(Properties,0);<br />
if (!Click && (~llListFindList(gAvWhitelist,[(string)llDetectedKey(0)])) )<br />
{<br />
llSetClickAction(CLICK_ACTION_SIT);<br />
llSetTimerEvent(10.0);<br />
llSay(0,"Please take a seat.");<br />
}<br />
else<br />
{<br />
llSetClickAction(CLICK_ACTION_TOUCH);<br />
if (llAvatarOnSitTarget() != NULL_KEY)<br />
{<br />
llSay(0,"Good bye!");<br />
}<br />
else<br />
{<br />
llSay(0,"Sorry. You are not allowed to sit here.");<br />
}<br />
llUnSit(llDetectedKey(0));<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
llSetTimerEvent(0.0);<br />
llSetClickAction(CLICK_ACTION_TOUCH);<br />
}<br />
}<br />
</source><br />
<br />
|spec<br />
|constants=<div id="box"><br />
==Constants==<br />
<div style="padding: 0.5em;"><br />
{{{!}} class="sortable" {{Prettytable}}<br />
{{!}}- {{Hl2}}<br />
! {{!}} Flag<br />
! title="Value" {{!}}<br />
! class="unsortable" {{!}} Description<br />
! class="unsortable" {{!}} Cursor<br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_NONE|integer|0|c=Performs the default action: when the prim is touched, touch events are triggered}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}<!--[[Image:]]--><br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_TOUCH|integer|0|c=When the prim is touched, touch events are triggered}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}<!--[[Image:]]--><br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_SIT|integer|1|c=When the prim is touched, the avatar sits upon it}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}[[File:SitActionCursor.png]]<br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_BUY|integer|2|c=When the prim is touched, the buy dialog is opened}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}[[File:SaleOneclickCursor.png]]<br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_PAY|integer|3|c=When the prim is touched, the pay dialog is opened}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}[[File:SaleOneclickCursor.png]]<br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_OPEN|integer|4|c=When the prim is touched, the object inventory dialog is opened}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}[[File:OpenOneclickCursor.png]]<br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_PLAY|integer|5|c=Play or pause parcel media on touch}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}[[Image:Toolplay.png]]<br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_OPEN_MEDIA|integer|6|c=Play parcel media on touch, no pause}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}[[Image:Toolmediaopen.png]]<br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_ZOOM|integer|7|c=Zoom}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}} ([[Viewer_2_Help|Viewer 2]])<br />
{{!}}[[Image:Toolzoom.png]]<br />
{{!}}-<br />
{{!}}{{LSL Const|CLICK_ACTION_DISABLED|integer|8|c=No click action. No touches detected or passed.}}<br />
{{!}}{{#var:value}}<br />
{{!}}{{#var:comment}}<br />
{{!}}<!--[[Image:]]--><br />
{{!}}}<br />
</div></div><br />
|signature=<br />
{{LSL Const/Signature|CLICK_ACTION_ZOOM|integer|7|c=Zoom}}<br />
|helpers<br />
|also_functions={{LSL DefineRow||[[llPassTouches]]}}<br />
|also_tests<br />
|also_events=<br />
{{LSL DefineRow||[[touch_start]]}}<br />
{{LSL DefineRow||[[touch]]}}<br />
{{LSL DefineRow||[[touch_end]]}}<br />
|also_articles={{LSL DefineRow||{{LSLGC|Detected}}}}<br />
<br />
|history=<br />
* Introduced in SL Client 1.19.1(0)<br />
* [[CLICK_ACTION_ZOOM]] added in SL Server 1.32 and [[Viewer_2_Help|Viewer 2]]<br />
|cat1=Prim<br />
|cat2=Touch<br />
|cat3=Sit<br />
|cat4=Money<br />
|cat5=Media<br />
|cat6=Effects<br />
|cat7=Click Action<br />
|cat8<br />
}}</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/sandbox&diff=1209914User:Toady Nakamura/sandbox2021-02-24T16:03:25Z<p>Toady Nakamura: Blanked the page</p>
<hr />
<div></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/sandbox&diff=1209913User:Toady Nakamura/sandbox2021-02-24T16:02:05Z<p>Toady Nakamura: Created page with "string KEYPAD = "76543210"; float COUNT_X = 1; // Number of buttons (horizontal) float COUNT_Y = 8; // Number of buttons (vertical) string av_name; key av_key; def..."</p>
<hr />
<div>string KEYPAD = "76543210";<br />
<br />
float COUNT_X = 1; // Number of buttons (horizontal)<br />
float COUNT_Y = 8; // Number of buttons (vertical)<br />
string av_name;<br />
key av_key;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSetTexture("1ea06fad-1520-15d0-4f6d-c2d422f5a073", ALL_SIDES);<br />
llSetObjectName(llKey2Name(llGetOwner()) + "'s Fancy Demo Touch!");<br />
}<br />
<br />
touch_start(integer num)<br />
{<br />
vector touched_pos = llDetectedTouchST(0);<br />
integer index = llFloor(touched_pos.x * COUNT_X) + <br />
llFloor(touched_pos.y * COUNT_Y) * (integer) COUNT_X;<br />
string touch_button = llGetSubString(KEYPAD, index, index);<br />
<br />
av_name = llDetectedName(0);<br />
av_key = llDetectedKey(0);<br />
<br />
llMessageLinked(LINK_SET, 0, touch_button, av_key);<br />
}<br />
<br />
link_message(integer sib, integer n, string msg, key id ) <br />
{<br />
string toucher_name = llKey2Name(id);<br />
<br />
if ( msg == "0" ) { }// do nothing // Title Section <br />
<br />
if ( msg == "1" )<br />
{ <br />
string greeting = "Welcome , " + toucher_name + "!";<br />
llRegionSayTo(id, 0, greeting);<br />
} <br />
<br />
if ( msg == "2" ) // wiki page<br />
{ <br />
string info = "Visit my SL Wiki Page!";<br />
string url = "http://wiki.secondlife.com/wiki/User:Toady_Nakamura";<br />
llLoadURL(id, info, url);<br />
llRegionSayTo(id, 0, "Push the button on the drop down to go to my SL Wiki Page, http://wiki.secondlife.com/wiki/User:Toady_Nakamura !");<br />
}<br />
<br />
if ( msg == "3" ) //object details<br />
{ <br />
list details = llGetObjectDetails(id, ([OBJECT_NAME, OBJECT_POS, OBJECT_ROT]));<br />
<br />
llRegionSayTo(id, 0, " Details about you!<br />
\n Name: " + llList2String(details, 0) +<br />
"\n Position: " + llList2String(details, 1) + <br />
"\n Rotation: " + llList2String(details, 2));<br />
}<br />
<br />
if ( msg == "4" )<br />
{ <br />
key groupKey = "adda7cb5-d7ee-3e03-0bea-a27c77bbb2b3";<br />
string groupName = "Happy Hippsters";<br />
<br />
llRegionSayTo(id, 0, "Click the link to join the group '" + groupName + "'\n"<br />
+ "secondlife:///app/group/" + (string)groupKey + "/about");<br />
}<br />
<br />
if ( msg == "5" )<br />
{ <br />
key sound_UUID = "71a2b035-8a33-9cb3-e71b-895b515d119f";<br />
llPlaySound(sound_UUID, 1.0);<br />
}<br />
<br />
if ( msg == "6" )<br />
{ <br />
llRegionSayTo(id, 0,"This may take several seconds to gather the data!");<br />
llRegionSayTo(id, 0,<br />
" Region Name : " + llGetRegionName() + <br />
"\n Sim Host Name : " + llGetSimulatorHostname() + <br />
"\n Region Time : " + (string)llGetRegionTimeDilation() +<br />
"\n Region FPS : " + (string)llGetRegionFPS() );<br />
}<br />
<br />
if ( msg == "7" )<br />
{ <br />
vector homepos = llGetPos(); <br />
llSetPos(homepos + < 0,0,0.5 >);<br />
llRegionSayTo(id, 0, "hopping you understand, <3 Toady!");<br />
llSleep(5.0);<br />
llSetPos(homepos);<br />
}<br />
}<br />
}</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User_talk:Toady_Nakamura&diff=1209740User talk:Toady Nakamura2020-12-02T07:27:40Z<p>Toady Nakamura: for class tomorrow i will clean up later</p>
<hr />
<div>Leave me a message !!! [[User:Toady Nakamura|Toady Nakamura]] 23:44, 5 July 2012 (PDT)\<br />
<br />
<source lang="lsl2"><br />
//Teleporters use the Changed Event <br />
<br />
<br />
// —— Global variables <br />
vector gDestination = <000,000,000>; // don’t change in class ! (see note one)<br />
<br />
integer gAccessMode = 1; // Change who can use the teleporter: 1 - public, 2 - owner, 3 - group.<br />
<br />
//—- all for hover text<br />
string gText = "Sit here for fun teleport"; // hover text<br />
vector gTextColor = < 0.42 , 1.0 , 0.42 > ; // color of hover text <br />
float gAlpha = 1.0; // transparency of hover text<br />
<br />
//====Script starts here with default ==========<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSitTarget(<0.0, 0.0, 0.51>, ZERO_ROTATION);<br />
llSetSitText("Teleport");<br />
llSetTouchText("Teleport");<br />
llSetText(gText, gTextColor, 1.0);<br />
llSetClickAction(CLICK_ACTION_SIT);<br />
<br />
vector offset = llGetPos() + < 0, 0, 10 >;<br />
gDestination = gDestination + offset;<br />
}<br />
<br />
changed(integer change) <br />
{<br />
if (change & CHANGED_LINK)<br />
{<br />
key USER = llAvatarOnSitTarget();<br />
<br />
if (llGetAgentSize(USER) != ZERO_VECTOR) // it’s really an avatar!<br />
{<br />
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br />
if (gDestination == <0.0,0.0,0.0>) // destination not set !! <br />
{<br />
llUnSit(USER); // unsit user<br />
llOwnerSay("WARNING ! Teleporter destination is set to 0,0,0. Aborting.");<br />
}<br />
integer access_granted = FALSE; // did not let this proceed<br />
<br />
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br />
if (gAccessMode == 1) // 1 is public, anyone can use<br />
{ access_granted = TRUE;} // you are good to go!<br />
// . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />
else if (gAccessMode == 2) // 2 is owner, so owner only<br />
{<br />
if (USER == llGetOwner()) // if user is the same as owner <br />
{ access_granted = TRUE; } // you are good to go!<br />
else<br />
{<br />
llUnSit(USER);<br />
llSay(0,"Sorry, " + llKey2Name(USER) + "teleporter for owner use only.");<br />
}<br />
}<br />
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br />
else if (gAccessMode == 3) // 3 is group, so only same group as rezzed<br />
{<br />
if (llSameGroup(USER)) // if user is in same group<br />
{ access_granted = TRUE; } // they are good to go!<br />
else<br />
{<br />
llUnSit(USER); <br />
llSay(0,"Sorry," + llKey2Name(USER) + " teleporter for group use only.");<br />
}<br />
}<br />
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . <br />
if (access_granted) // Yippie, you have permission! <br />
{<br />
vector _InitPos = llGetPos(); // gets starting position<br />
llSetRegionPos(gDestination); // sends to destination<br />
llUnSit(USER); // unsit ! <br />
llSetRegionPos(_InitPos); // go back to start pos<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
</source><br />
<br />
<br />
<source lang="lsl2"><br />
//Counts down from 5 to 1, then can do something else<br />
default<br />
{<br />
state_entry()<br />
{<br />
integer count = 5;<br />
do<br />
{<br />
<br />
llSay(0, (string)count);<br />
<br />
// wait a sec<br />
llSleep(1.0);<br />
}<br />
while (--index);<br />
<br />
llWhisper(0, "I am done counting now.");<br />
}<br />
}<br />
</source><br />
<br />
== Debug error ==<br />
<br />
Um I am sorry if I am going about this the wrong way but from what I can tell this was the only way to talk on the wiki and I had a question about the LSL 101 Logic page, the example script in particular, I copied it(sort of, I actually typed it out because of the note at the bottom) in the LSLEditor community edition and ran the debug... thing, and got the error "Field 'n' is never assigned to, and will always have its default value" <br />
<br />
I was wondering if this was an actual issue, and I wonder this because I have no actual coding knowledge. I apologize profusely if I have the wrong person or posted this where I shouldn't have. If you would like to see how it came out exactly I will of course provide what was written.<br />
<br />
--[[User:Rohise Resident|Rohise Resident]] 22:56, 9 October 2012 (PDT)<br />
<br />
== Variable names ==<br />
Greetings, I rewrote your example script on [[User:Toady_Nakamura/Simple_Recording_Tipjar]]. For sake of readability, please use variable names that actually mean something amd not i, m, n and what not. Your doing yourself a favor by doing so! -- [[User:Kireji Haiku|Kireji Haiku]] 11:18, 19 October 2012 (PDT)<br />
:I replied on your talk page, as is customary. You did not reply and you wiped out my reply to you. [[User:Toady Nakamura|Toady Nakamura]] 10:07, 4 November 2012 (PST)<br />
<br />
== Regarding your question about lists in LSL on [[User_talk:Strife Onizuka]] 's page: ==<br />
<br />
Please read [[User:Kireji_Haiku/How_to_deal_with_lists_in_LSL|this intro of how to iterate over a list in LSL]]. Hope it helps, kind regards. -- [[User:Kireji Haiku|Kireji Haiku]] 12:40, 5 November 2012 (PST)<br />
<br />
== Your simple listen script ==<br />
<br />
You do say at the top of your talk page "Leave me a message !!!" ... so I am :)<br />
<br />
I couldn't resist commenting on your recently posted script. Easiest is if I post the script here with my comments inserted (enclosed within ** **)<br />
<br />
(content omitted)<br />
[[User:Omei Qunhua|Omei Qunhua]] 01:38, 29 January 2014 (PST)<br />
:Thank you for your comments, you corrected a script I expect my students to correct in class so I have removed your corrections here so they don't cheat and just use yours. [[User:Toady Nakamura|Toady Nakamura]] 14:16, 11 March 2014 (PDT)<br />
<br />
== [[User:Toady_Nakamura/Give_Anything]]: ==<br />
<br />
Try this instead?<br />
<br />
<source lang="lsl2"><br />
vector floattext_color = < 1.0, 1.0, 1.0>;<br />
string floattext_text = "Put your floating message here.";<br />
string foldername = "Put the name of the folder they will get here.";<br />
<br />
list contents;<br />
<br />
default<br />
{<br />
changed(integer change)<br />
{<br />
if (change & (CHANGED_OWNER | CHANGED_INVENTORY))<br />
llResetScript();<br />
}<br />
<br />
state_entry()<br />
{<br />
llSetText(floattext_text, floattext_color, 1.0);<br />
<br />
integer c = llGetInventoryNumber(INVENTORY_ALL);<br />
integer i = 0;<br />
<br />
// for-loops below have the same effect in this particular example<br />
<br />
// for (; i < c; i += 1) ...;<br />
// for (; i < c; i++) ...;<br />
// for (; i < c; ++i) ...;<br />
<br />
for (i = 0; i < c; i = i + 1)<br />
{<br />
string n = llGetInventoryName(INVENTORY_ALL, i);<br />
integer t = llGetInventoryType(n);<br />
<br />
// if you include INVENTORY_SCRIPT below, you need to<br />
// check against if (n != llGetScriptName()) as well to not give away this script<br />
<br />
if (t & (INVENTORY_LANDMARK | INVENTORY_NOTECARD | INVENTORY_OBJECT))<br />
contents += n;<br />
}<br />
}<br />
<br />
touch_start(integer num_detected)<br />
{<br />
key avatarKey = llDetectedKey(0);<br />
string avatarName = llDetectedName(0);<br />
<br />
if (llGetListLength(contents))<br />
llGiveInventoryList(avatarKey, foldername, contents);<br />
<br />
llOwnerSay(avatarName + " got supplies.");<br />
}<br />
}<br />
</source><br />
<br />
Cheers! '''[[User:Kireji_Haiku|Kireji Haiku]]''' <sup><small>([[User talk:Kireji_Haiku|talk]]|[[Special:Contributions/Kireji_Haiku|contribs]])</small></sup> 01:02, 2 September 2014 (PDT)<br />
<br />
==next up==<br />
<source lang="lsl2"><br />
default<br />
{<br />
state_entry()<br />
{<br />
integer p;<br />
for (p = 2; p <= llGetNumberOfPrims(); p++)<br />
llSetLinkPrimitiveParamsFast(p, [PRIM_NAME, llGetObjectName(), PRIM_DESC, llGetObjectDesc()]);<br />
}<br />
}<br />
</source><br />
<br />
that way I don't frogget to do it.</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Kireji_Haiku/How_to_deal_with_lists_in_LSL&diff=1209677User:Kireji Haiku/How to deal with lists in LSL2020-10-08T22:50:21Z<p>Toady Nakamura: /* finally clean code */ changing <lsl> to <source lang="lsl2"> & </source></p>
<hr />
<div>NOTE: Firstly look to see if there is a [[:Category:LSL_Functions|built-in function]] available to process your list the way you wish. This will always be faster than coding your own loops.<br />
e.g. [[llListFindList]](), [[llListStatistics]]()<br />
<br />
This page is more about different ways to code loops, rather than about processing lists.<br />
<br />
==How to deal with lists in the Linden Scripting Language:==<br />
<br />
<div id="box"><br />
<br />
==the basics==<br />
<br />
<div style="padding: 0.5em"><br />
A.) Usual [[List]] with 10 items:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
</source><br />
<br />
B.) Start with a [[for]]-loop:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index = 0;<br />
for (index = 0;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
C.) Resetting the value to 0 for index was redundant so we can skip that:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index = 0;<br />
for (;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
D.) Setting the default value to 0 is also redundant, since LSL initializes [[Integer|integers]] as 0. Keep in mind that other languages may not do this.<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index;<br />
for (;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
E.) Calculating the list length every step is also redundant because the length doesn't change - at least in the example demonstrated here.<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index;<br />
for (;index < lengthOfList;index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
</div></div><br />
<div id="box"><br />
<br />
==slightly more advanced now==<br />
<div style="padding: 0.5em"><br />
Now the index for items in a list of ten is either:<br />
<br />
{| width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''plain English'''<br />
! '''using positive indices'''<br />
! '''using negative indices'''<br />
|-<br />
||first item of a list of ten<br />
||0<br />
||-10<br />
|-<br />
||second item of a list of ten<br />
||1<br />
||-9<br />
|-<br />
||third item of a list of ten<br />
||2<br />
||-8<br />
|-<br />
||fourth item of a list of ten<br />
||3<br />
||-7<br />
|-<br />
||fifth item of a list of ten<br />
||4<br />
||-6<br />
|-<br />
||sixth item of a list of ten<br />
||5<br />
||-5<br />
|-<br />
||seventh item of a list of ten<br />
||6<br />
||-4<br />
|-<br />
||eight item of a list of ten<br />
||7<br />
||-3<br />
|-<br />
||ninth item of a list of ten<br />
||8<br />
||-2<br />
|-<br />
||tenth item of a list of ten<br />
||9<br />
||-1<br />
|}<br />
<br />
While ++index is fractionally faster than index++ in LSO, using the preferred Mono VM, there is no timing difference. See [[LSL_Hacks]] for more details.<br />
<br />
We could start with -11 and increment first before doing something, instead of the other way around before... as long as the index stays negative. We can write:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index = -lengthOfList - 1;<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
<br />
Now trying to simplify the math for calculating the index default value we can make use of the [[LSL_Operators]] and initialize with '''bitwise-NOT of the length''' which is the same as <code>-1*length - 1</code> or the negative length minus one:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~lengthOfList;<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
<br />
as you might have seen by now, we can merge two lines in the middle:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
<br />
and because index should have a negative value while looping and the loop stops when index reaches zero, we can change the code to:<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
for (;index;++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
<br />
and improve readability by using a [[while]]-loop:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
while (++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index = -1;// attention again! index is -1 before the first round<br />
// each round index is incremented FIRST before being compared to lengthOfList and then used within the loop<br />
while (++index < lengthOfList)<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
</div><br />
</div><br />
<div id="box"><br />
<br />
==finally clean code==<br />
<br />
<div style="padding: 0.5em"><br />
<br />
and try to get rid of the bitwise-NOT because some people find it hard to read. The positive side effect of the next step is that you need to increment one step less in total and the loop runs the first step directly without checking first for a conditional statement:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// negative length now!<br />
integer index = -llGetListLength(listOfTenItems);<br />
<br />
do<br />
{<br />
//do something<br />
}<br />
while (++index);<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index;<br />
do<br />
{<br />
//do something<br />
}<br />
while (++index < lengthOfList);<br />
</source><br />
|}<br />
</div><br />
</div></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Kireji_Haiku/How_to_deal_with_lists_in_LSL&diff=1209676User:Kireji Haiku/How to deal with lists in LSL2020-10-08T22:49:23Z<p>Toady Nakamura: /* slightly more advanced now */changing <lsl> to <source lang="lsl2"> & </source></p>
<hr />
<div>NOTE: Firstly look to see if there is a [[:Category:LSL_Functions|built-in function]] available to process your list the way you wish. This will always be faster than coding your own loops.<br />
e.g. [[llListFindList]](), [[llListStatistics]]()<br />
<br />
This page is more about different ways to code loops, rather than about processing lists.<br />
<br />
==How to deal with lists in the Linden Scripting Language:==<br />
<br />
<div id="box"><br />
<br />
==the basics==<br />
<br />
<div style="padding: 0.5em"><br />
A.) Usual [[List]] with 10 items:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
</source><br />
<br />
B.) Start with a [[for]]-loop:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index = 0;<br />
for (index = 0;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
C.) Resetting the value to 0 for index was redundant so we can skip that:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index = 0;<br />
for (;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
D.) Setting the default value to 0 is also redundant, since LSL initializes [[Integer|integers]] as 0. Keep in mind that other languages may not do this.<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index;<br />
for (;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
E.) Calculating the list length every step is also redundant because the length doesn't change - at least in the example demonstrated here.<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index;<br />
for (;index < lengthOfList;index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
</div></div><br />
<div id="box"><br />
<br />
==slightly more advanced now==<br />
<div style="padding: 0.5em"><br />
Now the index for items in a list of ten is either:<br />
<br />
{| width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''plain English'''<br />
! '''using positive indices'''<br />
! '''using negative indices'''<br />
|-<br />
||first item of a list of ten<br />
||0<br />
||-10<br />
|-<br />
||second item of a list of ten<br />
||1<br />
||-9<br />
|-<br />
||third item of a list of ten<br />
||2<br />
||-8<br />
|-<br />
||fourth item of a list of ten<br />
||3<br />
||-7<br />
|-<br />
||fifth item of a list of ten<br />
||4<br />
||-6<br />
|-<br />
||sixth item of a list of ten<br />
||5<br />
||-5<br />
|-<br />
||seventh item of a list of ten<br />
||6<br />
||-4<br />
|-<br />
||eight item of a list of ten<br />
||7<br />
||-3<br />
|-<br />
||ninth item of a list of ten<br />
||8<br />
||-2<br />
|-<br />
||tenth item of a list of ten<br />
||9<br />
||-1<br />
|}<br />
<br />
While ++index is fractionally faster than index++ in LSO, using the preferred Mono VM, there is no timing difference. See [[LSL_Hacks]] for more details.<br />
<br />
We could start with -11 and increment first before doing something, instead of the other way around before... as long as the index stays negative. We can write:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index = -lengthOfList - 1;<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
<br />
Now trying to simplify the math for calculating the index default value we can make use of the [[LSL_Operators]] and initialize with '''bitwise-NOT of the length''' which is the same as <code>-1*length - 1</code> or the negative length minus one:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~lengthOfList;<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
<br />
as you might have seen by now, we can merge two lines in the middle:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
<br />
and because index should have a negative value while looping and the loop stops when index reaches zero, we can change the code to:<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
for (;index;++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
<br />
and improve readability by using a [[while]]-loop:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
while (++index)<br />
{<br />
//do something<br />
}<br />
</source><br />
||<br />
<source lang="lsl2"><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index = -1;// attention again! index is -1 before the first round<br />
// each round index is incremented FIRST before being compared to lengthOfList and then used within the loop<br />
while (++index < lengthOfList)<br />
{<br />
//do something<br />
}<br />
</source><br />
|}<br />
</div><br />
</div><br />
<div id="box"><br />
<br />
==finally clean code==<br />
<br />
<div style="padding: 0.5em"><br />
<br />
and try to get rid of the bitwise-NOT because some people find it hard to read. The positive side effect of the next step is that you need to increment one step less in total and the loop runs the first step directly without checking first for a conditional statement:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// negative length now!<br />
integer index = -llGetListLength(listOfTenItems);<br />
<br />
do<br />
{<br />
//do something<br />
}<br />
while (++index);<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index;<br />
do<br />
{<br />
//do something<br />
}<br />
while (++index < lengthOfList);<br />
</lsl><br />
|}<br />
</div><br />
</div></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Kireji_Haiku/How_to_deal_with_lists_in_LSL&diff=1209675User:Kireji Haiku/How to deal with lists in LSL2020-10-08T22:46:51Z<p>Toady Nakamura: /* the basics */</p>
<hr />
<div>NOTE: Firstly look to see if there is a [[:Category:LSL_Functions|built-in function]] available to process your list the way you wish. This will always be faster than coding your own loops.<br />
e.g. [[llListFindList]](), [[llListStatistics]]()<br />
<br />
This page is more about different ways to code loops, rather than about processing lists.<br />
<br />
==How to deal with lists in the Linden Scripting Language:==<br />
<br />
<div id="box"><br />
<br />
==the basics==<br />
<br />
<div style="padding: 0.5em"><br />
A.) Usual [[List]] with 10 items:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
</source><br />
<br />
B.) Start with a [[for]]-loop:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index = 0;<br />
for (index = 0;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
C.) Resetting the value to 0 for index was redundant so we can skip that:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index = 0;<br />
for (;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
D.) Setting the default value to 0 is also redundant, since LSL initializes [[Integer|integers]] as 0. Keep in mind that other languages may not do this.<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index;<br />
for (;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
<br />
E.) Calculating the list length every step is also redundant because the length doesn't change - at least in the example demonstrated here.<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index;<br />
for (;index < lengthOfList;index++)<br />
{<br />
//do something<br />
}<br />
</source><br />
</div></div><br />
<div id="box"><br />
<br />
==slightly more advanced now==<br />
<div style="padding: 0.5em"><br />
Now the index for items in a list of ten is either:<br />
<br />
{| width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''plain English'''<br />
! '''using positive indices'''<br />
! '''using negative indices'''<br />
|-<br />
||first item of a list of ten<br />
||0<br />
||-10<br />
|-<br />
||second item of a list of ten<br />
||1<br />
||-9<br />
|-<br />
||third item of a list of ten<br />
||2<br />
||-8<br />
|-<br />
||fourth item of a list of ten<br />
||3<br />
||-7<br />
|-<br />
||fifth item of a list of ten<br />
||4<br />
||-6<br />
|-<br />
||sixth item of a list of ten<br />
||5<br />
||-5<br />
|-<br />
||seventh item of a list of ten<br />
||6<br />
||-4<br />
|-<br />
||eight item of a list of ten<br />
||7<br />
||-3<br />
|-<br />
||ninth item of a list of ten<br />
||8<br />
||-2<br />
|-<br />
||tenth item of a list of ten<br />
||9<br />
||-1<br />
|}<br />
<br />
While ++index is fractionally faster than index++ in LSO, using the preferred Mono VM, there is no timing difference. See [[LSL_Hacks]] for more details.<br />
<br />
We could start with -11 and increment first before doing something, instead of the other way around before... as long as the index stays negative. We can write:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index = -lengthOfList - 1;<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
<br />
Now trying to simplify the math for calculating the index default value we can make use of the [[LSL_Operators]] and initialize with '''bitwise-NOT of the length''' which is the same as <code>-1*length - 1</code> or the negative length minus one:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~lengthOfList;<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
<br />
as you might have seen by now, we can merge two lines in the middle:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
<br />
and because index should have a negative value while looping and the loop stops when index reaches zero, we can change the code to:<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
for (;index;++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
<br />
and improve readability by using a [[while]]-loop:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
while (++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index = -1;// attention again! index is -1 before the first round<br />
// each round index is incremented FIRST before being compared to lengthOfList and then used within the loop<br />
while (++index < lengthOfList)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
</div><br />
</div><br />
<div id="box"><br />
<br />
==finally clean code==<br />
<br />
<div style="padding: 0.5em"><br />
<br />
and try to get rid of the bitwise-NOT because some people find it hard to read. The positive side effect of the next step is that you need to increment one step less in total and the loop runs the first step directly without checking first for a conditional statement:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// negative length now!<br />
integer index = -llGetListLength(listOfTenItems);<br />
<br />
do<br />
{<br />
//do something<br />
}<br />
while (++index);<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index;<br />
do<br />
{<br />
//do something<br />
}<br />
while (++index < lengthOfList);<br />
</lsl><br />
|}<br />
</div><br />
</div></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Kireji_Haiku/How_to_deal_with_lists_in_LSL&diff=1209674User:Kireji Haiku/How to deal with lists in LSL2020-10-08T22:43:44Z<p>Toady Nakamura: /* the basics */ changing <lsl> to <source lang="lsl2"> & </source></p>
<hr />
<div>NOTE: Firstly look to see if there is a [[:Category:LSL_Functions|built-in function]] available to process your list the way you wish. This will always be faster than coding your own loops.<br />
e.g. [[llListFindList]](), [[llListStatistics]]()<br />
<br />
This page is more about different ways to code loops, rather than about processing lists.<br />
<br />
==How to deal with lists in the Linden Scripting Language:==<br />
<br />
<div id="box"><br />
<br />
==the basics==<br />
<br />
<div style="padding: 0.5em"><br />
Usual [[List]] with 10 items:<br />
<br />
<source lang="lsl2"> <br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
</source><br />
<br />
Then start with a [[for]]-loop:<br />
<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index = 0;<br />
for (index = 0;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
<br />
Resetting the value to 0 for index was redundant so we can skip that:<br />
<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index = 0;<br />
for (;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
<br />
Setting the default value to 0 is redundant, too, since LSL initializes [[Integer|integers]] as 0. Keep in mind that other languages may not do this.<br />
<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
integer index;<br />
for (;index < llGetListLength(listOfTenItems);index++)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
<br />
Calculating the list length every step is redundant too because the length doesn't change - at least in the example demonstrated here.<br />
<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index;<br />
for (;index < lengthOfList;index++)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
</div><br />
</div><br />
<div id="box"><br />
<br />
==slightly more advanced now==<br />
<div style="padding: 0.5em"><br />
Now the index for items in a list of ten is either:<br />
<br />
{| width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''plain English'''<br />
! '''using positive indices'''<br />
! '''using negative indices'''<br />
|-<br />
||first item of a list of ten<br />
||0<br />
||-10<br />
|-<br />
||second item of a list of ten<br />
||1<br />
||-9<br />
|-<br />
||third item of a list of ten<br />
||2<br />
||-8<br />
|-<br />
||fourth item of a list of ten<br />
||3<br />
||-7<br />
|-<br />
||fifth item of a list of ten<br />
||4<br />
||-6<br />
|-<br />
||sixth item of a list of ten<br />
||5<br />
||-5<br />
|-<br />
||seventh item of a list of ten<br />
||6<br />
||-4<br />
|-<br />
||eight item of a list of ten<br />
||7<br />
||-3<br />
|-<br />
||ninth item of a list of ten<br />
||8<br />
||-2<br />
|-<br />
||tenth item of a list of ten<br />
||9<br />
||-1<br />
|}<br />
<br />
While ++index is fractionally faster than index++ in LSO, using the preferred Mono VM, there is no timing difference. See [[LSL_Hacks]] for more details.<br />
<br />
We could start with -11 and increment first before doing something, instead of the other way around before... as long as the index stays negative. We can write:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index = -lengthOfList - 1;<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
<br />
Now trying to simplify the math for calculating the index default value we can make use of the [[LSL_Operators]] and initialize with '''bitwise-NOT of the length''' which is the same as <code>-1*length - 1</code> or the negative length minus one:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~lengthOfList;<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
<br />
as you might have seen by now, we can merge two lines in the middle:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
for (;index < 0;++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
<br />
and because index should have a negative value while looping and the loop stops when index reaches zero, we can change the code to:<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
for (;index;++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index; // pay attention here! index is 0 before loop starts and<br />
for (;index < lengthOfList;++index) // doesn't get incremented until JUST before the second round<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
<br />
and improve readability by using a [[while]]-loop:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// it's bitwise-NOT (~) instead of minus (-)<br />
integer index = ~llGetListLength(listOfTenItems);<br />
while (++index)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index = -1;// attention again! index is -1 before the first round<br />
// each round index is incremented FIRST before being compared to lengthOfList and then used within the loop<br />
while (++index < lengthOfList)<br />
{<br />
//do something<br />
}<br />
</lsl><br />
|}<br />
</div><br />
</div><br />
<div id="box"><br />
<br />
==finally clean code==<br />
<br />
<div style="padding: 0.5em"><br />
<br />
and try to get rid of the bitwise-NOT because some people find it hard to read. The positive side effect of the next step is that you need to increment one step less in total and the loop runs the first step directly without checking first for a conditional statement:<br />
<br />
{| class="sortable" width="100%" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''if indexes can be negative'''<br />
! '''if indexes can NOT be negative'''<br />
|-<br />
||<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
<br />
// negative length now!<br />
integer index = -llGetListLength(listOfTenItems);<br />
<br />
do<br />
{<br />
//do something<br />
}<br />
while (++index);<br />
</lsl><br />
||<br />
<lsl><br />
list listOfTenItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];<br />
integer lengthOfList = llGetListLength(listOfTenItems);<br />
<br />
integer index;<br />
do<br />
{<br />
//do something<br />
}<br />
while (++index < lengthOfList);<br />
</lsl><br />
|}<br />
</div><br />
</div></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1207835User:Toady Nakamura2018-11-24T00:39:03Z<p>Toady Nakamura: /* Useful Scripts */</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Ribbon Particle|Rainbow Ribbon Tail to Wear]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Rainbow particle tail to wear.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Ribbon_Particle&diff=1207834User:Toady Nakamura/Ribbon Particle2018-11-24T00:36:45Z<p>Toady Nakamura: ribbon particle example that used to be on SL forums, but vanished</p>
<hr />
<div>*Visit my SL wiki home page for more simple scripts that work. -- [[User:Toady Nakamura|Toady Nakamura]]<br />
<br />
'''Build instructions:'''<br />
* create a box, install script.<br />
* wear & walk<br />
<br />
<source lang="lsl2"><br />
//// "Rainbow Tail" <br />
<br />
<br />
default {<br />
attach(key id) <br />
{ llSetRot( llEuler2Rot(<PI_BY_TWO,0,0>) ); <br />
}<br />
<br />
state_entry()<br />
{<br />
<br />
llParticleSystem( [<br />
PSYS_PART_FLAGS, 0<br />
| PSYS_PART_INTERP_COLOR_MASK <br />
| PSYS_PART_INTERP_SCALE_MASK <br />
| PSYS_PART_EMISSIVE_MASK <br />
| PSYS_PART_RIBBON_MASK <br />
, <br />
PSYS_PART_START_SCALE, <0.25, 0.25, FALSE>, <br />
PSYS_PART_END_SCALE, <0.05, 0.05, FALSE>, <br />
PSYS_PART_START_COLOR, <1.00,1.00,1.00>,<br />
PSYS_PART_END_COLOR, <1.00,1.00,1.00>, <br />
PSYS_PART_START_ALPHA, 1.0, <br />
PSYS_PART_END_ALPHA, 0.0, <br />
PSYS_PART_MAX_AGE, 2.0, <br />
<br />
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP, <br />
PSYS_SRC_TEXTURE, "db833e5e-9069-5891-de5b-1b56b073e718", <br />
<br />
PSYS_SRC_BURST_RATE, 0.1, <br />
PSYS_SRC_BURST_PART_COUNT, 1, <br />
PSYS_SRC_ANGLE_BEGIN, 0.00*PI, <br />
PSYS_SRC_ANGLE_END, 0.01*PI, <br />
PSYS_SRC_BURST_SPEED_MIN, 0.0, <br />
PSYS_SRC_BURST_SPEED_MAX, 0.09,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.1> <br />
] ); <br />
} <br />
</source></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1204740User:Toady Nakamura2016-10-17T20:24:34Z<p>Toady Nakamura: test edit</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=Tic_Tac_Toe/Game_Logic_Two&diff=1199979Tic Tac Toe/Game Logic Two2016-04-24T22:30:29Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>{{LSL Header}}<br />
{{:Tic Tac Toe/navigation}}<br />
<br />
Now with our uploader in place, we can add another message to the TouchDisplay script to color them red when we detect three in a row:<br />
<br />
<source lang="lsl2"><br />
// Locations of various bits on the texture<br />
float e_pos_s = 0.75;<br />
float e_pos_t = 0.75;<br />
float x_pos_s = 0.75;<br />
float x_pos_t = 0.25;<br />
float o_pos_s = 0.25;<br />
float o_pos_t = 0.25;<br />
<br />
// Face on wjich the texture lives<br />
integer DISPLAY_FACE = 4;<br />
vector RED = <1,0,0>;<br />
vector WHITE = <1,1,1>;<br />
<br />
// Message constants<br />
integer MSG_RESET = 0;<br />
integer MSG_TOUCH = 1;<br />
integer MSG_SET_X = 2;<br />
integer MSG_SET_O = 3;<br />
integer MSG_IDLE = 4;<br />
integer MSG_IDLE_TOUCH = 5;<br />
integer MSG_WIN = 6;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
// If we are in the the root prim...<br />
if (llGetLinkNumber() < 2)<br />
{<br />
// ... disable ourselves<br />
llSetScriptState(llGetScriptName(), FALSE);<br />
llSleep(2);<br />
}<br />
<br />
// Reset color and texture<br />
llSetColor(WHITE, DISPLAY_FACE);<br />
llOffsetTexture(e_pos_s, e_pos_t, DISPLAY_FACE);<br />
}<br />
<br />
touch_start(integer touching_agents)<br />
{<br />
while (touching_agents--)<br />
{<br />
llMessageLinked(LINK_ROOT, MSG_TOUCH, "", llDetectedKey(touching_agents));<br />
} <br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_SET_X) state x;<br />
if (msg_id == MSG_SET_O) state o;<br />
if (msg_id == MSG_IDLE) state idle;<br />
}<br />
}<br />
<br />
state x<br />
{<br />
state_entry()<br />
{<br />
llOffsetTexture(x_pos_s, x_pos_t, DISPLAY_FACE);<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_RESET) state default;<br />
if (msg_id == MSG_IDLE) state idle;<br />
if (msg_id == MSG_WIN) llSetColor(RED, DISPLAY_FACE);<br />
}<br />
}<br />
<br />
state o<br />
{<br />
state_entry()<br />
{<br />
llOffsetTexture(o_pos_s, o_pos_t, DISPLAY_FACE);<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_RESET) state default;<br />
if (msg_id == MSG_IDLE) state idle;<br />
if (msg_id == MSG_WIN) llSetColor(RED, DISPLAY_FACE);<br />
}<br />
}<br />
<br />
state idle<br />
{<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_RESET) state default;<br />
}<br />
<br />
touch_start(integer touching_agents)<br />
{<br />
llMessageLinked(LINK_ROOT, MSG_IDLE_TOUCH, "", NULL_KEY);<br />
}<br />
} <br />
</source><br />
<br />
We then go into the Controller script and add the logic to detect the game end:<br />
<br />
<source lang="lsl2"><br />
// Message constants<br />
integer MSG_RESET = 0;<br />
integer MSG_TOUCH = 1;<br />
integer MSG_SET_X = 2;<br />
integer MSG_SET_O = 3;<br />
integer MSG_IDLE = 4;<br />
integer MSG_IDLE_TOUCH = 5;<br />
integer MSG_WIN = 6;<br />
<br />
// Game timeout<br />
integer GAME_TIMEOUT = 20;<br />
<br />
// Game state<br />
key player_x;<br />
key player_o;<br />
string turn;<br />
string game;<br />
<br />
// Helper function to linearize our 3x3 array<br />
string at(integer u, integer v)<br />
{<br />
integer p = u*3+v;<br />
return llGetSubString(game, p, p);<br />
}<br />
<br />
// return TRUE if game ends<br />
integer game_ends(string player, integer move)<br />
{<br />
game = llInsertString(llDeleteSubString(game, move, move), move, player);<br />
llSay(0, "game = "+game);<br />
<br />
// Check if this made three in a row<br />
integer u = move / 3;<br />
integer v = move % 3;<br />
integer i;<br />
integer c;<br />
<br />
// check horizontal<br />
c = 0;<br />
for (i = 0; i < 3; i++) if (at(i, v) == player) c++;<br />
if (c == 3)<br />
{<br />
// The magic number "2" is needed because the smallest child prim index is 2<br />
for (i = 0; i < 3; i++) llMessageLinked(2 + 3*i + v, MSG_WIN, "", NULL_KEY);<br />
return TRUE;<br />
}<br />
<br />
// check vertical<br />
c = 0;<br />
for (i = 0; i < 3; i++) if (at(u, i) == player) c++;<br />
if (c == 3)<br />
{<br />
// The magic number "2" is needed because the smallest child prim index is 2<br />
for (i = 0; i < 3; i++) llMessageLinked(2 + 3*u + i, MSG_WIN, "", NULL_KEY);<br />
return TRUE;<br />
}<br />
<br />
// check if we are on one diagonal<br />
c = 0;<br />
if (u == v) for (i = 0; i < 3; i++) if (at(i, i) == player) c++;<br />
if (c == 3)<br />
{<br />
// The magic number "2" is needed because the smallest child prim index is 2<br />
for (i = 0; i < 3; i++) llMessageLinked(2 + 4*i, MSG_WIN, "", NULL_KEY);<br />
return TRUE;<br />
}<br />
<br />
// check if we are on the other diagonal<br />
c = 0;<br />
if (u + v == 2) for (i = 0; i < 3; i++) if (at(i, 2-i) == player) c++;<br />
if (c == 3)<br />
{<br />
// Arithmetic has been applied, reconstruction left as an exercise to the reader<br />
for (i = 0; i < 3; i++) llMessageLinked(4 + 2*i, MSG_WIN, "", NULL_KEY);<br />
return TRUE;<br />
}<br />
<br />
// Check if there are any spaces left<br />
if (llSubStringIndex(game, "-") < 0) return TRUE;<br />
<br />
// Game goes on<br />
return FALSE;<br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
player_x = NULL_KEY;<br />
player_o = NULL_KEY;<br />
game = "---------";<br />
turn = "x";<br />
<br />
llMessageLinked(LINK_ALL_CHILDREN, MSG_RESET, "", NULL_KEY);<br />
state playing;<br />
}<br />
}<br />
<br />
state playing<br />
{<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_TOUCH)<br />
{<br />
llSay(0, "touch from "+(string)from);<br />
if (turn == "x" && NULL_KEY == player_x)<br />
{<br />
llSetTimerEvent(0);<br />
llMessageLinked(from, MSG_SET_X, "", NULL_KEY);<br />
player_x = id;<br />
if (game_ends(turn, from-2)) state idle; // magic "2" = smallest link prim index<br />
turn = "o";<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
}<br />
else if (turn == "o" && NULL_KEY == player_o)<br />
{<br />
llSetTimerEvent(0);<br />
llMessageLinked(from, MSG_SET_O, "", NULL_KEY);<br />
player_o = id;<br />
if (game_ends(turn, from-2)) state idle; // magic "2" = smallest link prim index<br />
turn = "x";<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
}<br />
else if (turn == "x" && id == player_x)<br />
{<br />
llSetTimerEvent(0);<br />
llMessageLinked(from, MSG_SET_X, "", NULL_KEY);<br />
if (game_ends(turn, from-2)) state idle; // magic "2" = smallest link prim index<br />
turn = "o";<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
}<br />
else if (turn == "o" && id == player_o)<br />
{<br />
llSetTimerEvent(0);<br />
llMessageLinked(from, MSG_SET_O, "", NULL_KEY);<br />
if (game_ends(turn, from-2)) state idle; // magic "2" = smallest link prim index<br />
turn = "x";<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSetTimerEvent(0);<br />
state idle;<br />
}<br />
}<br />
<br />
state idle<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "state idle");<br />
llMessageLinked(LINK_ALL_CHILDREN, MSG_IDLE, "", NULL_KEY);<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_IDLE_TOUCH) state default;<br />
}<br />
}<br />
</source><br />
<br />
Note that we don't have to check all possibilities, but only those which could be made possible by the last move.<br />
<br />
We also needed to reorder our handling of incoming touch events slightly to ensure that the event timer is off when we process moves.<br />
<br />
Then we type <tt>\1 update</tt> into the chat and play a couple of games to test.<br />
<br />
Done.<br />
<br />
Have fun!</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=Tic_Tac_Toe/Version_Control&diff=1199978Tic Tac Toe/Version Control2016-04-24T22:29:29Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>{{LSL Header}}<br />
{{:Tic Tac Toe/navigation}}<br />
<br />
So, let's interrupt our quest for the tic tac toe game and build a little infrastructure.<br />
<br />
Here, I've added two scripts: RootNanny and LinkNanny. The RootNanny listens for a <tt>/1 update</tt> and starts a remote upload of a predetermined list of scripts onto the linked prims. <br />
<br />
<source lang="lsl2"><br />
// Message constants<br />
integer MSG_RESET = 0;<br />
integer MSG_LINK_QUERY = 10;<br />
integer MSG_LINK_REPLY = 11;<br />
<br />
// Globals to propagate<br />
string version = "1.4";<br />
integer pin = 321;<br />
<br />
<br />
// State<br />
integer current_link_nr;<br />
<br />
// Stuff to send out<br />
list remote_scripts = [ "TouchDisplay", "LinkNanny" ];<br />
<br />
request_next_object_id(integer link_nr)<br />
{<br />
// Send message, transmitting pin, hoping to get back objectid<br />
llMessageLinked(link_nr, MSG_LINK_QUERY, (string)pin, NULL_KEY);<br />
<br />
// Set timer in case link isn't replying<br />
llSetTimerEvent(2); // 2 secs seems generous<br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
string name = llGetObjectName();<br />
integer space = llSubStringIndex(name, " v");<br />
if (space < 0) llSetObjectName(name + " v" + version);<br />
else llSetObjectName(llDeleteSubString(name, space+2, -1) + version);<br />
llListen(1, "", llGetOwner(), "update");<br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
state uploading;<br />
}<br />
}<br />
<br />
state uploading<br />
{<br />
state_entry()<br />
{<br />
current_link_nr = llGetNumberOfPrims();<br />
// Check if it's more than one<br />
if (1 < current_link_nr)<br />
{<br />
// avatars sitting on us get added at the end, so subtract...<br />
while (llGetAgentSize(llGetLinkKey(current_link_nr)))<br />
--current_link_nr;<br />
request_next_object_id(current_link_nr);<br />
}<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (from == current_link_nr && msg_id == MSG_LINK_REPLY)<br />
{<br />
llSetTimerEvent(0); // Cancel timeout<br />
integer i;<br />
for (i = 0; i < llGetListLength(remote_scripts); ++i)<br />
{<br />
string script = llList2String(remote_scripts, i);<br />
llSay(0, "Uploading '"+script+"' to link nr "+(string)current_link_nr);<br />
llRemoteLoadScriptPin(id, script, pin, TRUE, 0);<br />
}<br />
current_link_nr--;<br />
if (1 < current_link_nr)<br />
{<br />
request_next_object_id(current_link_nr);<br />
}<br />
else<br />
{<br />
llSay(0, "Done uploading remote scripts.");<br />
state default;<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSay(0, "Failed to receive reply from link nr "+(string)current_link_nr);<br />
current_link_nr--;<br />
if (1 < current_link_nr)<br />
{<br />
request_next_object_id(current_link_nr);<br />
}<br />
else<br />
{<br />
llSay(0, "Done uploading remote scripts.");<br />
state default;<br />
}<br />
}<br />
}<br />
</source><br />
<br />
The LinkNannys are there to set the remote upload pin and to reply with their object id:<br />
<br />
<source lang="lsl2"><br />
// Message constants<br />
integer MSG_RESET = 0;<br />
integer MSG_LINK_QUERY = 10;<br />
integer MSG_LINK_REPLY = 11;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
// If we are in the the root prim...<br />
if (llGetLinkNumber() < 2)<br />
{<br />
// ... disable ourselves<br />
llSetScriptState(llGetScriptName(), FALSE);<br />
llSleep(2);<br />
}<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_LINK_QUERY)<br />
{<br />
// Set pin given<br />
llSetRemoteScriptAccessPin((integer)str);<br />
// Tell caller who we are<br />
llMessageLinked(from, MSG_LINK_REPLY, "", llGetKey());<br />
}<br />
}<br />
}<br />
</source><br />
<br />
With this structure, we can keep all scripts in the root prim, and the appropriate ones will be replicated to all the remaining prims, greatly simplifying the task of developing those scripts. <br />
<br />
For this specific project, this is almost overkill, and could have been done simpler - for example, we don't really need to ask every prim what their object id is, because we can use [[llGetLinkKey]](). But for larger projects, you can use the LinkNannys to return the list of scripts in that prim, and thereby remove the need to keep a mapping of which scripts go where - in this project we just happen to luck out simply because all the linked prims are identical. In most real projects, this is not the case. Also, if you are really paranoid, you would negotiate a separate pin for every upload.<br />
<br />
This implementation also illustrates some common idioms and ways to avoid scaling pitfalls as your project gets larger.<br />
<br />
Note how we query each link in sequence, the end of every event handler having an [[llMessageLinked]]() call to request the next one. This is a common pattern, used to process notecards, email, http requests and much else. Here it is again:<br />
<br />
<source lang="lsl2"><br />
<br />
state process<br />
{<br />
state_entry()<br />
{<br />
llSetTimerEvent(<some_timeout>);<br />
llMessageLinked(...<get_first_object>...);<br />
}<br />
<br />
link_message(...)<br />
{<br />
// Disable timer<br />
llSetTimerEvent(0);<br />
<br />
// Process data<br />
...<br />
// exit if we know we're done<br />
if (<end_condition>) state done_processing;<br />
<br />
// Set timeout again<br />
llSetTimerEvent(<some_timeout>);<br />
llMessageLinked(...<get_next_object>...);<br />
}<br />
<br />
timer()<br />
{<br />
// We didn't get a response<br />
llSetTimerEvent(0);<br />
<br />
// Error handling - retries, whatever...<br />
...<br />
}<br />
}<br />
</source><br />
<br />
A naive implementation of this would have simply broadcast the query to all prims and relied on the event queue to stash them and serve them back one by one. This is dangerous as the event queue is of undefined size, and due to the delay involved with running [[llRemoteLoadScriptPin]](), any subsequent replies could easily be flushed out by whatever other events may be traversing your build.<br />
<br />
Also note the timeout. Never assume anything is they way you wish it is. In your previous run you could have distributed a script which kills off the LinkNanny, or maybe you just screwed up the LinkNanny" itself... Debugging sucks, so add as many catchers as you can.<br />
<br />
Finally, note the code that changes the object name to reflect the current version. In a real product, you would use a separate object to contain an updater which will itself upload the latest version of the scripts onto your build, and having this code in place allows you to see whether the updater was applied.<br />
<br />
Two more observations:<br />
<br />
The scripts were added as new scripts and not shoehorned into the existing scripts, for two reasons:<br />
# We want to make it easy to reuse the framework for other projects;<br />
# We want to preserve full freedom in the application to change state as needed. Note that this allows us to use states to prevent any incorrect processing of multiple "/1 upload" commands.<br />
<br />
Maintaining remote scripts in the root prim is convenient, but we don't want them to actually run there. Therefore we place the following ''suicide code'' at the state_entry handler of the default state in the DisplayTouch and LinkNanny scripts:<br />
<br />
<source lang="lsl2"><br />
default<br />
{<br />
state_entry()<br />
{<br />
// If we are in the the root prim...<br />
if (llGetLinkNumber() < 2)<br />
{<br />
// ... disable ourselves<br />
llSetScriptState(llGetScriptName(), FALSE);<br />
// ... and sleep to ensure nothing else gets executed<br />
llSleep(2);<br />
}<br />
}<br />
<br />
...<br />
}<br />
</source><br />
<br />
One slight drawback of the LinkNanny is that we will need to distribute it one initial time by hand, but we're comforted by the fact that it will be the last time we need to actually open the contents of the linked prims.</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=Tic_Tac_Toe/Game_Logic_One&diff=1199977Tic Tac Toe/Game Logic One2016-04-24T22:27:35Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>{{LSL Header}}<br />
{{:Tic Tac Toe/navigation}}<br />
<br />
Now we're ready to flesh out the game. We get a little stricter in our if else cascade and keep track of who's turn it is. We also record the game state.<br />
<br />
<source lang="lsl2"><br />
// Message constants<br />
integer MSG_RESET = 0;<br />
integer MSG_TOUCH = 1;<br />
integer MSG_SET_X = 2;<br />
integer MSG_SET_O = 3;<br />
integer MSG_IDLE = 4;<br />
integer MSG_IDLE_TOUCH = 5;<br />
<br />
// Game timeout<br />
integer GAME_TIMEOUT = 20;<br />
<br />
// Game state<br />
key player_x;<br />
key player_o;<br />
string turn;<br />
string game;<br />
<br />
update_game(string player, integer move)<br />
{<br />
game = llInsertString(llDeleteSubString(game, move, move), move, player);<br />
llSay(0, "game = "+game);<br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
player_x = NULL_KEY;<br />
player_o = NULL_KEY;<br />
game = "---------";<br />
turn = "x";<br />
<br />
llMessageLinked(LINK_ALL_CHILDREN, MSG_RESET, "", NULL_KEY);<br />
state playing;<br />
}<br />
}<br />
<br />
state playing<br />
{<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_TOUCH)<br />
{<br />
llSay(0, "touch from "+(string)from);<br />
if (turn == "x" && NULL_KEY == player_x)<br />
{<br />
player_x = id;<br />
update_game(turn, from-2);<br />
turn = "o";<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
llMessageLinked(from, MSG_SET_X, "", NULL_KEY);<br />
}<br />
else if (turn == "o" && NULL_KEY == player_o)<br />
{<br />
player_o = id;<br />
update_game(turn, from-2);<br />
turn = "x";<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
llMessageLinked(from, MSG_SET_O, "", NULL_KEY);<br />
}<br />
else if (turn == "x" && id == player_x)<br />
{<br />
update_game(turn, from-2);<br />
turn = "o";<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
llMessageLinked(from, MSG_SET_X, "", NULL_KEY);<br />
}<br />
else if (turn == "o" && id == player_o)<br />
{<br />
update_game(turn, from-2);<br />
turn = "x";<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
llMessageLinked(from, MSG_SET_O, "", NULL_KEY);<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSetTimerEvent(0);<br />
state idle;<br />
}<br />
}<br />
<br />
state idle<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "state idle");<br />
llMessageLinked(LINK_ALL_CHILDREN, MSG_IDLE, "", NULL_KEY);<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_IDLE_TOUCH) state default;<br />
}<br />
}<br />
</source><br />
<br />
A note about data structures... as you know, lsl doesn't have any. All it has is lists and strings. Use strings. Lists are worthless unless you have ''wildly'' heterogenous data, a need for a little extra speed and not much data:<br />
<br />
* Strings are slower, but use memory more efficiently<br />
* Lists are faster, but gobble up memory at an alarming rate<br />
<br />
Store constant width fields in constant length records - your strings can be as long as can fit into whatever remains of the 16k allocated to your script.<br />
<br />
If you run out of memory, a common technique is to write ''data server scripts'' with just a tiny query API via linked messages.<br />
<br />
Everything is there except for the game end checker. If the game ends by winning, we'd like to highlight the winning squares, which would require adding a message and code to the 9 scripts in the X/O boxes. I guess 9 isn't too bad, but still annoying to have to open 9 inventories, delete and drag in a new verion of the script. It's easy to misclick, and becomes old pretty quick - and there is a better way...</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=Tic_Tac_Toe/Root_Objects&diff=1199976Tic Tac Toe/Root Objects2016-04-24T22:26:37Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>{{LSL Header}}<br />
{{:Tic Tac Toe/navigation}}<br />
<br />
I know that distributed logic is all the rage, but for a simple project like this, centralized is good. We're going to keep the user interface bits as dumb as possible and have the central controller script decide what happens.<br />
<br />
Before we go even further, we need to think a little how the players are going to interact with this game. How are we going to know who is playing and whose turn it is?<br />
<br />
When designing these things, try to make things as simple and automatic as possible. Don't make the users go through a sign-in process or other complicated sit-ups. In this game I decided to use the following process:<br />
<br />
* a game is ''idle'' if it hasn't been played in a while or has ended. It can then be reset by clicking on any cube.<br />
* the first player to make a move on a reset game is X<br />
* the second player to make a move is O<br />
* play continues until game ends or times out, after which it becomes idle.<br />
<br />
One thing that isn't immediately obvious is that we can't have the X/O cubes make the decision on whether to change state, since they don't have the full information. Only the central controller script can change the states of the X/O cubes. So we need to split off the state change from the touch event handlers and use a message handler to change the states.<br />
<br />
So let's talk about messages. This game is going to be one linkset, so we will use link messages. They are actually quite nice as long as you keep good message discipline. In this case we will decide to use the following convention:<br />
<br />
<pre><br />
llMessageLinked(<target>, <message-id>, <string-arg>, <key-arg>);<br />
</pre><br />
<br />
Message ids will be constants defined at the beginning of every script we use. We never overload the meaning of a message id - we have more than enough integers to not make this necessary. We avoid encoding data into the message id. The string arg and the key arg provide more than enough space for codes.<br />
<br />
Note: Constants are expensive - unfortunately. Seems like 20 bytes per integer constant, and as the project gets larger it puts you into an unfortunate vicious circle - so ''magic numbers'' will have to do - but use them only if really needed, and make sure you put a comment next to them.<br />
<br />
Let's look at the X/O cube's script. Note the proper way to code a touch event handler. That integer argument getting passed in //is// important, even if in 99% of the cases it will be "1". It does happen that multiple touch events get packed into one, especially in a competitive game, and ignoring a user action is just about the worst insult you can inflict. So do make the effort of writing that silly while loop.<br />
<br />
<source lang="lsl2"><br />
// Locations of various bits on the texture<br />
float e_pos_s = 0.75;<br />
float e_pos_t = 0.75;<br />
float x_pos_s = 0.75;<br />
float x_pos_t = 0.25;<br />
float o_pos_s = 0.25;<br />
float o_pos_t = 0.25;<br />
<br />
// Face on which the texture lives<br />
integer display_face = 4;<br />
<br />
// Message constants<br />
integer MSG_RESET = 0;<br />
integer MSG_TOUCH = 1;<br />
integer MSG_SET_X = 2;<br />
integer MSG_SET_O = 3;<br />
integer MSG_IDLE = 4;<br />
integer MSG_IDLE_TOUCH = 5;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llOffsetTexture(e_pos_s, e_pos_t, display_face);<br />
}<br />
<br />
touch_start(integer touching_agents)<br />
{<br />
while (touching_agents--)<br />
{<br />
llMessageLinked(LINK_ROOT, MSG_TOUCH, "", llDetectedKey(touching_agents));<br />
} <br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_SET_X) state x;<br />
if (msg_id == MSG_SET_O) state o;<br />
if (msg_id == MSG_IDLE) state idle;<br />
}<br />
}<br />
<br />
state x<br />
{<br />
state_entry()<br />
{<br />
llOffsetTexture(x_pos_s, x_pos_t, display_face);<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_RESET) state default;<br />
if (msg_id == MSG_IDLE) state idle;<br />
}<br />
}<br />
<br />
state o<br />
{<br />
state_entry()<br />
{<br />
llOffsetTexture(o_pos_s, o_pos_t, display_face);<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_RESET) state default;<br />
if (msg_id == MSG_IDLE) state idle;<br />
}<br />
}<br />
<br />
state idle<br />
{<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_RESET) state default;<br />
}<br />
<br />
touch_start(integer touching_agents)<br />
{<br />
llMessageLinked(LINK_ROOT, MSG_IDLE_TOUCH, "", NULL_KEY);<br />
}<br />
} <br />
</source><br />
<br />
Note that as long as the game is in progress, there //is// no touch event for the x and o states, thereby trivially avoiding bad touches.<br />
<br />
As promised, state changes happen only when the central controller says so...<br />
<br />
Another detail: the message sent on an idle touch is different that the touch message in the default state. Since at that point we really do not care who clicked, we omit the while loop.<br />
<br />
And now let's look at the central controller script:<br />
<br />
<source lang="lsl2"><br />
// Message constants<br />
integer MSG_RESET = 0;<br />
integer MSG_TOUCH = 1;<br />
integer MSG_SET_X = 2;<br />
integer MSG_SET_O = 3;<br />
integer MSG_IDLE = 4;<br />
integer MSG_IDLE_TOUCH = 5;<br />
<br />
<br />
// Game timeout<br />
integer GAME_TIMEOUT = 20;<br />
<br />
// Game state<br />
key player_x;<br />
key player_o;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "state default");<br />
player_x = NULL_KEY;<br />
player_o = NULL_KEY;<br />
llMessageLinked(LINK_ALL_CHILDREN, MSG_RESET, "", NULL_KEY);<br />
state playing;<br />
}<br />
}<br />
<br />
state playing<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "state playing");<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
llSay(0, "from = "+(string)from+" msg_id = "+(string)msg_id);<br />
if (msg_id == MSG_TOUCH)<br />
{<br />
llSay(0, "touch from "+(string)from);<br />
if (NULL_KEY == player_x)<br />
{<br />
player_x = id;<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
llMessageLinked(from, MSG_SET_X, "", NULL_KEY);<br />
}<br />
else if (NULL_KEY == player_o)<br />
{<br />
player_o = id;<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
llMessageLinked(from, MSG_SET_O, "", NULL_KEY);<br />
}<br />
else if (id == player_x)<br />
{<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
llMessageLinked(from, MSG_SET_X, "", NULL_KEY);<br />
}<br />
else if (id == player_o)<br />
{<br />
llSetTimerEvent(GAME_TIMEOUT);<br />
llMessageLinked(from, MSG_SET_O, "", NULL_KEY);<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSetTimerEvent(0);<br />
state idle;<br />
}<br />
}<br />
<br />
state idle<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "state idle");<br />
llMessageLinked(LINK_ALL_CHILDREN, MSG_IDLE, "", NULL_KEY);<br />
}<br />
<br />
link_message(integer from, integer msg_id, string str, key id)<br />
{<br />
if (msg_id == MSG_IDLE_TOUCH) state default;<br />
}<br />
}<br />
</source><br />
<br />
That one starts with a cut & paste job to import the message constants. Now wouldn't <tt>#include</tt> be nice here - but hence the rule about these being constants - if later other scripts need more, you only add those you need.<br />
<br />
In the previous section we talked about states and when to use them, and here is an example of the other use case for states: a bootstrapping process. Note that during an actual game, we stay in a single state. We only change state when the event behaviour is changing.<br />
<br />
Note how we pass along the id of the touchers from the X/O Cube script.<br />
<br />
Note how we keep resetting the timeout. In particular, it is necessary to explicitly disable the timer event when leaving a state, since for some reason the timer setting persists and will come and cause trouble when re-entering that state.<br />
<br />
No actual game logic is implemented yet, but it should be easy to see where this is going...<br />
<br />
At this point, we can simply copy the X/O Cubes to make 9. The script's message will be identifiable by the link number. It is important to remember how those numbers get assigned when you build the object. Essentially, every new object you add to your selection prior to linking will be number one, shifting everyone else up one number. You then select your intended root prim ''last'', then execute the link command (ctrl-l).<br />
<br />
As your project grows, you may find that link numbers are too fragile, especially if you keep refining the shape of your object. An alternative solution would be to use [[llGetObjectName]]() or [[llGetObjectDesc]]() to store a symbolic link name and pass it along in your [[llMessageLinked]]() calls.</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=Tic_Tac_Toe/Leaf_Objects&diff=1199975Tic Tac Toe/Leaf Objects2016-04-24T22:21:55Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>{{LSL Header}}<br />
{{:Tic Tac Toe/navigation}}<br />
<br />
It all begins with a cube...<br />
<br />
I'm basically a bottom up guy, so I tend to start with the user interface elements first. Of course you need a general idea of what your project is gonna look like when it's done, but it is not worthwhile to spend too much time beyond the general idea. The logic of the project will guide you along, and investing too much time on the grand plan will make you reluctant to change your mind if the evolution of the project seems to indicate a problem.<br />
<br />
So, for tic tac toe, it seems like a 3x3 array of cubes mounted on a backboard is a good general idea, so let's start with the cube.<br />
<br />
Obviously, we want to be able to display three states: empty, X and O. We could use three textures, but that would be quite wasteful - besides costing L$30, they would all rez separately and make the game slow at the beginning until all the textures are cached.<br />
<br />
A much better technique is to use a single texture, displaying only a small part of it at a time using [[llOffsetTexture]]. Not only do we save L$20, but the whole texture rezzes once and we only have to go through the fuzzies once.<br />
<br />
This is an approximate look of the texture I used:<br />
<pre><br />
+--------------------+<br />
| @@ @@ @@@@@ |<br />
| @@ @@ @@ @@ |<br />
| @@@ @@ @@ |<br />
| @@ @@ @@ @@ |<br />
| @@ @@ @@@@@ |<br />
| |<br />
| |<br />
| |<br />
| |<br />
| |<br />
+--------------------+<br />
</pre><br />
In this example, I chose to use states to represent the three possible - well - states of the cube. The question on when to use states and when to represent state in data can be difficult, but I found the following guidelines to work pretty well:<br />
<br />
* Use states when the ''event-processing'' in each state differs significantly '''and''' there is not much data to be shared among the states.<br />
<br />
* Use data to store the state when event processing remains essentially the same or you need to share data between states anyway.<br />
<br />
The reason why event processing matters is because every state gets to have its own event handlers. This is both good and bad. It means you can efficiently ignore events irrelevant to the state by simply not providing a handler, but it also means that if you do provide a handler, you need to do all the setup work for it - hence the recommendations above.<br />
<br />
In practice, the use cases for states are mostly two:<br />
* "leaf" objects with no dependents, so no worries about other objects having to know about your state<br />
* "boot" sequences where you expect to end up in a final, semi-permanent single state.<br />
<br />
In our case here, we fall squarely into the first, and since we are definitively a leaf object ''and'' we do wish to modify our event processing behaviour depending on the state, states are the way to go.<br />
<br />
And here's the code going into the cube:<br />
<br />
<source lang="lsl2">// Cached texture positions<br />
<br />
float e_pos_s = 0.75;<br />
float e_pos_t = 0.75;<br />
<br />
float x_pos_s = 0.75;<br />
float x_pos_t = 0.25;<br />
<br />
float o_pos_s = 0.25;<br />
float o_pos_t = 0.25;<br />
<br />
integer display_face = 4;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llOffsetTexture(e_pos_s, e_pos_t, display_face);<br />
}<br />
<br />
touch_start(integer total_number)<br />
{<br />
state x;<br />
}<br />
}<br />
<br />
state x<br />
{<br />
state_entry()<br />
{<br />
llOffsetTexture(x_pos_s, x_pos_t, display_face);<br />
}<br />
<br />
touch_start(integer total_number)<br />
{<br />
state o;<br />
}<br />
}<br />
<br />
state o<br />
{<br />
state_entry()<br />
{<br />
llOffsetTexture(o_pos_s, o_pos_t, display_face);<br />
}<br />
<br />
touch_start(integer total_number)<br />
{<br />
state default;<br />
}<br />
}</source><br />
<br />
At this point we're just playing around, and the code doesn't do anything immediately useful, it just cycles through the states on touch.</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1199857User:Toady Nakamura2016-04-12T18:21:32Z<p>Toady Nakamura: adding one</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
|-<br />
||[[User:Toady_Nakamura/Give_to_Group|Give to Group]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives object from inventory to toucher - only if toucher is in same group.<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Give_to_Group&diff=1199856User:Toady Nakamura/Give to Group2016-04-12T18:18:46Z<p>Toady Nakamura: new page</p>
<hr />
<div>Put this script into a prim along with <br />
<br />
== Give Only to Group ==<br />
<source lang="lsl2"><br />
<br />
default<br />
{<br />
touch_start(integer num) // touch start records toucher "number"<br />
{<br />
<br />
integer touches = 0; // start at zero<br />
<br />
do<br />
{<br />
if (llDetectedGroup(touches)) // if the toucher is same group as box is set<br />
{<br />
llGiveInventory(llDetectedKey(touches), llGetInventoryName(INVENTORY_OBJECT,0));<br />
// give the object in inventory to the toucher<br />
}<br />
else // otherwise<br />
{<br />
llWhisper(0, "Please set your tag to the correct group for this box."); <br />
// inform toucher they have the wrong tag on<br />
}<br />
}<br />
<br />
while(num > ++touches);<br />
}<br />
}<br />
</source><br />
<br />
I got this script from a box of Free Scripts at NCI (New Citizens Inc.) in 2009. <br />
*Visit my SL wiki home page for more simple scripts that work. -- [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1199804User:Toady Nakamura2016-04-01T22:17:28Z<p>Toady Nakamura: trying to make my photo active again</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
<br />
== Toad's Hall ==<br />
[[File:Toady Nakamura Creative License.png|150px|thumb|left|The real me]]<br />
<br />
[[File:April Fools Destination Grendels.jpg|150px|thumb|left|April Fools]]<br />
<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1199802User:Toady Nakamura2016-04-01T22:11:52Z<p>Toady Nakamura: april fools</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png <br><br />
File:April Fools Destination Grendels.jpg<br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
[[File:April Fools Destination Grendels.jpg|thumb|left April Fools!!]]<br />
<br />
== Toad's Hall ==<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=File:April_Fools_Destination_Grendels.jpg&diff=1199800File:April Fools Destination Grendels.jpg2016-04-01T22:10:16Z<p>Toady Nakamura: Don't miss the Fifth Annual April Fool's craziness by Frog-n-Cat Productions... Touch everything, trust nothing, find the kraken, prezzies galore... Take the Rocket at the entry point !!</p>
<hr />
<div>Don't miss the Fifth Annual April Fool's craziness by Frog-n-Cat Productions... Touch everything, trust nothing, find the kraken, prezzies galore... Take the Rocket at the entry point !!</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Smile_Script&diff=1199714User:Toady Nakamura/Smile Script2016-03-11T22:03:23Z<p>Toady Nakamura: </p>
<hr />
<div>For humanoid avatars... this script in a prim & worn will make your avatar smile!!<br />
*Found in a 2008 freebie, modified slightly by [[User:Toady Nakamura|Toady Nakamura]]<br />
*There is a version in the LSL wiki > examples, but it's not annotated as to HOW it works<br />
* See [https://wiki.secondlife.com/wiki/Internal_Animations here for a list of Internal Animations]<br />
<br />
<source lang="lsl2"><br />
default<br />
{<br />
state_entry()<br />
{ <br />
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);<br />
// getting permission here is automatic, because the item is worn<br />
// triggers run_time_permissions event<br />
}<br />
<br />
run_time_permissions(integer perm)<br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION)<br />
{<br />
llSetTimerEvent(5.0); <br />
// since permission was granted set a 5 second timer event<br />
}<br />
}<br />
<br />
timer()<br />
{ <br />
llStartAnimation("express_toothsmile");<br />
// every five seconds, replay the system animation<br />
}<br />
<br />
attach(key moo)<br />
{<br />
if(moo)<br />
{ <br />
llResetScript();<br />
// when the item is worn, reset the script<br />
}<br />
}<br />
}<br />
<br />
</source><br />
<br />
<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Smile_Script&diff=1199713User:Toady Nakamura/Smile Script2016-03-11T22:02:27Z<p>Toady Nakamura: added link to https://wiki.secondlife.com/wiki/Internal_Animations</p>
<hr />
<div>For humanoid avatars... this script in a prim & worn will make your avatar smile!!<br />
*Found in a 2008 freebie, modified slightly by [[User:Toady Nakamura|Toady Nakamura]]<br />
*There is a version in the LSL wiki > examples, but it's not annotated as to HOW it works<br />
* See [https://wiki.secondlife.com/wiki/Internal_Animations here for a list of Internal Animations]<br />
<source lang="lsl2"><br />
<br />
<br />
<br />
default<br />
{<br />
state_entry()<br />
{ <br />
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);<br />
// getting permission here is automatic, because the item is worn<br />
// triggers run_time_permissions event<br />
}<br />
<br />
run_time_permissions(integer perm)<br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION)<br />
{<br />
llSetTimerEvent(5.0); <br />
// since permission was granted set a 5 second timer event<br />
}<br />
}<br />
<br />
timer()<br />
{ <br />
llStartAnimation("express_toothsmile");<br />
// every five seconds, replay the system animation<br />
}<br />
<br />
attach(key moo)<br />
{<br />
if(moo)<br />
{ <br />
llResetScript();<br />
// when the item is worn, reset the script<br />
}<br />
}<br />
}<br />
<br />
</source><br />
<br />
<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User_talk:Toady_Nakamura&diff=1199660User talk:Toady Nakamura2016-03-03T23:10:17Z<p>Toady Nakamura: new snippit</p>
<hr />
<div>Leave me a message !!! [[User:Toady Nakamura|Toady Nakamura]] 23:44, 5 July 2012 (PDT)<br />
<br />
<lsl><br />
//Counts down from 5 to 1, then can do something else<br />
default<br />
{<br />
state_entry()<br />
{<br />
integer count = 5;<br />
do<br />
{<br />
<br />
llSay(0, (string)count);<br />
<br />
// wait a sec<br />
llSleep(1.0);<br />
}<br />
while (--index);<br />
<br />
llWhisper(0, "I am done counting now.");<br />
}<br />
}<br />
</lsl><br />
<br />
== Debug error ==<br />
<br />
Um I am sorry if I am going about this the wrong way but from what I can tell this was the only way to talk on the wiki and I had a question about the LSL 101 Logic page, the example script in particular, I copied it(sort of, I actually typed it out because of the note at the bottom) in the LSLEditor community edition and ran the debug... thing, and got the error "Field 'n' is never assigned to, and will always have its default value" <br />
<br />
I was wondering if this was an actual issue, and I wonder this because I have no actual coding knowledge. I apologize profusely if I have the wrong person or posted this where I shouldn't have. If you would like to see how it came out exactly I will of course provide what was written.<br />
<br />
--[[User:Rohise Resident|Rohise Resident]] 22:56, 9 October 2012 (PDT)<br />
<br />
== Variable names ==<br />
Greetings, I rewrote your example script on [[User:Toady_Nakamura/Simple_Recording_Tipjar]]. For sake of readability, please use variable names that actually mean something amd not i, m, n and what not. Your doing yourself a favor by doing so! -- [[User:Kireji Haiku|Kireji Haiku]] 11:18, 19 October 2012 (PDT)<br />
:I replied on your talk page, as is customary. You did not reply and you wiped out my reply to you. [[User:Toady Nakamura|Toady Nakamura]] 10:07, 4 November 2012 (PST)<br />
<br />
== Regarding your question about lists in LSL on [[User_talk:Strife Onizuka]] 's page: ==<br />
<br />
Please read [[User:Kireji_Haiku/How_to_deal_with_lists_in_LSL|this intro of how to iterate over a list in LSL]]. Hope it helps, kind regards. -- [[User:Kireji Haiku|Kireji Haiku]] 12:40, 5 November 2012 (PST)<br />
<br />
== Your simple listen script ==<br />
<br />
You do say at the top of your talk page "Leave me a message !!!" ... so I am :)<br />
<br />
I couldn't resist commenting on your recently posted script. Easiest is if I post the script here with my comments inserted (enclosed within ** **)<br />
<br />
(content omitted)<br />
[[User:Omei Qunhua|Omei Qunhua]] 01:38, 29 January 2014 (PST)<br />
:Thank you for your comments, you corrected a script I expect my students to correct in class so I have removed your corrections here so they don't cheat and just use yours. [[User:Toady Nakamura|Toady Nakamura]] 14:16, 11 March 2014 (PDT)<br />
<br />
== [[User:Toady_Nakamura/Give_Anything]]: ==<br />
<br />
Try this instead?<br />
<br />
<lsl><br />
vector floattext_color = < 1.0, 1.0, 1.0>;<br />
string floattext_text = "Put your floating message here.";<br />
string foldername = "Put the name of the folder they will get here.";<br />
<br />
list contents;<br />
<br />
default<br />
{<br />
changed(integer change)<br />
{<br />
if (change & (CHANGED_OWNER | CHANGED_INVENTORY))<br />
llResetScript();<br />
}<br />
<br />
state_entry()<br />
{<br />
llSetText(floattext_text, floattext_color, 1.0);<br />
<br />
integer c = llGetInventoryNumber(INVENTORY_ALL);<br />
integer i = 0;<br />
<br />
// for-loops below have the same effect in this particular example<br />
<br />
// for (; i < c; i += 1) ...;<br />
// for (; i < c; i++) ...;<br />
// for (; i < c; ++i) ...;<br />
<br />
for (i = 0; i < c; i = i + 1)<br />
{<br />
string n = llGetInventoryName(INVENTORY_ALL, i);<br />
integer t = llGetInventoryType(n);<br />
<br />
// if you include INVENTORY_SCRIPT below, you need to<br />
// check against if (n != llGetScriptName()) as well to not give away this script<br />
<br />
if (t & (INVENTORY_LANDMARK | INVENTORY_NOTECARD | INVENTORY_OBJECT))<br />
contents += n;<br />
}<br />
}<br />
<br />
touch_start(integer num_detected)<br />
{<br />
key avatarKey = llDetectedKey(0);<br />
string avatarName = llDetectedName(0);<br />
<br />
if (llGetListLength(contents))<br />
llGiveInventoryList(avatarKey, foldername, contents);<br />
<br />
llOwnerSay(avatarName + " got supplies.");<br />
}<br />
}<br />
</lsl><br />
<br />
Cheers! '''[[User:Kireji_Haiku|Kireji Haiku]]''' <sup><small>([[User talk:Kireji_Haiku|talk]]|[[Special:Contributions/Kireji_Haiku|contribs]])</small></sup> 01:02, 2 September 2014 (PDT)<br />
<br />
==next up==<br />
default {<br />
state_entry()<br />
{<br />
integer p;<br />
for (p = 2; p <= llGetNumberOfPrims(); p++)<br />
llSetLinkPrimitiveParamsFast(p, [PRIM_NAME, llGetObjectName(), PRIM_DESC, llGetObjectDesc()]);<br />
} }<br />
<br />
that way I don't frogget to do it.</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura&diff=1198828User:Toady Nakamura2016-01-11T21:44:36Z<p>Toady Nakamura: minor tweaks</p>
<hr />
<div>{{SL-hCard/2.0<br />
|color1=800080<br />
|color2=000<br />
|color3=990099<br />
|color4=008000<br />
|color5=ffeeff<br />
|name=Toady Nakamura<br />
|image=Toady Nakamura Creative License.png<br />
|rezday=January 6, 2007<br />
|about=Grendel's Children Designer<br />
|fields={{SL-hCard/field|NOW?|<br />
* Enjoys learning <br />
* Teaches at least one class a week!<br />
* Frustrated by lack of basic Wiki scripts<br />
}}<br />
}}<br />
<br />
<br />
== Toad's Hall ==<br />
I love finding useful scripts here in the Wiki, but most of them are aimed at AWESOME scripters, not beginners. I use this page to store handy scripts & links to helpful pages ... like the [[LSL_Library| Scripts Library]] & this link to [[User:Fred Gandt/Scripts/Functions|Fred Gandt's awesome userpage]] with tons of free scripts - especially stuff with string sorting.<br />
<br />
[[File:Toady_Nakamura.jpg|150px|thumb|left|The 2008 me]] I rezzed {{Age|06|01|2007}} days ago and learn something new every day.<br />
<br />
I edited a series of half-finished old tutorials called [[LSL_101/A_Gentle_Introduction|LSL 101]] - and got thru 'em all July 7, 2012. <br />
Working on an addon page on [https://wiki.secondlife.com/wiki/User:Toady_Nakamura/Sandbox Operators & Flow Control ] in my sandbox. July 28, 2012.<br />
<br />
I suggest new users check out [[LSL Style Guide]] on this wiki.<br />
<br />
== Useful Scripts ==<br />
{{KBcaution|These scripts are in my user space and intended for teaching purposes. Do not remove content from them, instead append changes to the bottom of each page and explain why yours are more awesome.}}<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Basic Scripts'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts.<br />
|-<br />
||[[User:Toady Nakamura/Touch Counting | Touch Counting]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Two scripts show how to count up or down as the box is touched.<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to change from dark to light<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Rotate|Touch Toggle Rotate]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to make a cylinder spin (like a record or CD)<br />
|-<br />
||[[User:Toady Nakamura/Two States Light|Two States Light]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Uses two states as an on/off switch<br />
|-<br />
||[[User:Toady Nakamura/Sound Looper|Sound Looper]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Three ways to make looped sound from any object.<br />
|-<br />
||[[User:Toady Nakamura/Simple Recording Tipjar|Simple Recording Tipjar]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Thanks giver & sets hover text with total amount donated.<br />
|-<br />
||[[User:Toady Nakamura/Simple Listener|Simple Listener]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||A simple listener that changes the color of the prim in response to commands.<br />
|-<br />
<br />
<br />
||[[User:Toady_Nakamura/Demo Typecast Random Float and Integer|Demo Typecast Random Float and Integer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Picks a random number and outputs as both float and integer. Helps students visualize the difference between float and integer data.<br />
|- {{Hl2}}<br />
! '''Particle Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Touch Toggle Particle|Touch Toggle Particle]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Touch to turn particles on and off<br />
|-<br />
||[[User:Toady Nakamura/Particle Sparkler Touch on off|Particle Sparkler Touch on off]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Sparkler for incendiary holidays like 4th July & Canada Day. Explains build & uses "Explode" pattern.<br />
|-<br />
||[[User:Toady Nakamura/Particle Mist for Fountains Script|Particle Mist for Fountains]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Nice small mist for fountains, small water features & fire logs. Uses "Explode" pattern.<br />
|-<br />
<br />
|- {{Hl2}}<br />
! '''Color Scripts'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Color_Chooser|Color chooser prim]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Change prim color, it tells owner new color vector & sets hover text with vector in new color.<br />
|-<br />
||[[User:Toady Nakamura/Random Color|Random Color]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object, randomly changes object color every two seconds.<br />
|- {{Hl2}}<br />
! '''Givers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Give Anything|Give Anything]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Five scripts from basic to more complicated help you give anything, but not scripts!<br />
|-<br />
||[[User:Toady Nakamura/Landmark Giver and Counter|Landmark Giver & Counter]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives any landmark in inventory; tells owner how many have been given.<br />
|-<br />
||[[User:Toady Nakamura/Give Random Object|Give Random Object]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Gives a random object from prim inventory to any toucher.<br />
<br />
|- {{Hl2}}<br />
! '''Timers'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady_Nakamura/Count down Timer|Count down Timer]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||How to count down, countdown timers!<br />
<br />
<br />
|- {{Hl2}}<br />
! '''Avatar Animations'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Hold Teddy Script|Hold Teddy Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear with an animation to animate avatar.<br />
|-<br />
||[[User:Toady Nakamura/Smile Script|Smile Script]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in object to wear, makes avatar smile with system animation<br />
|-<br />
||[[User:Toady Nakamura/Couples Poseball|Couples Poseball]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Makes synchronized poseballs<br />
|-{{Hl2}}<br />
! '''Useful Uses of Lists'''<br />
! ''' '''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Prim Contents Lister|Prim Contents Lister]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Put in prim with stuff, outputs list of stuff to your chat. Very helpful for inventory organization.<br />
|-<br />
|}<br />
<small>'''''I'm not being egotistical putting my name in every line! If anyone links to the Script Library, this format will slide into the table without trouble !'''''</small><br />
<br />
==Link flags==<br />
These are used for link_message scripts & others.<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Flag'''<br />
! '''Flag#'''<br />
! '''Description'''<br />
|-<br />
||LINK_ROOT <br />
||1<br />
||refers to the root prim in a multi-prim linked set (note)<br />
|-<br />
<br />
||LINK_SET <br />
||-1<br />
||refers to all prims<br />
|-<br />
<br />
||LINK_ALL_OTHERS <br />
||-2<br />
||refers to all other prims<br />
|-<br />
<br />
||LINK_ALL_CHILDREN <br />
||-3<br />
||refers to all children, (everything but the root)<br />
|-<br />
<br />
||LINK_THIS<br />
||-4<br />
||refers to the prim the script is in <br />
|-<br />
<br />
|}<br />
^ LINK_ROOT does not work on single prim objects. Unless there is an avatar sitting on the object. <br />
<br />
<br />
<br />
<br />
== SL Texture Constants & UUIDS ==<br />
* White Transparent = "59facb66-4a72-40a2-815c-7d9b42c56f60";<br />
* TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; <br />
* TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; <br />
* TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; <br />
* TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";<br />
<br />
<br />
Use this tag for Script Library Examples (simple stuff goes here)<br />
<br />
<pre>[[Category:LSL Examples]]</pre><br />
<br />
== SL Tutorials ==<br />
{{{!}}<br />
{{LSL DefineRow||[http://torley.com/office Visit Here for ''enlightenment'' today!]|Watch video tutorials and indulge your creative curiosity in Second Life...<br />
Learning, intrigue, and wild fun awaits ''you''...}}<br />
{{LSL DefineRow||[http://www.robinwood.com/Catalog/Technical/SL-Tuts/SLTutSet.html Robin Wood texture tutorials]|Best spot to get rid of white lines on alphas!!}}<br />
{{!}}}<br />
BTW, if you find more LSL tutorials, add them to the tuts page with this tag<br />
<pre><br />
{{LSLC|Tutorials|Item'sExactName}}<br />
</pre><br />
<br />
==Videos==<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! <br />
! '''Link'''<br />
! '''Description'''<br />
|-<br />
|1<br />
| [http://www.youtube.com/watch?v=SoHp22uo-vc '''The Wizard & The Ozimal,''' machinama ] <br />
| A film by '''Pyewacket Bellman''' <br />
|-<br />
|2<br />
|[http://treet.tv/shows/designingworlds '''Designing Worlds''' ]<br />
| with Saffia Widdershins on Treet.tv January 25, 2011 <br />
|-<br />
|3<br />
|[http://www.youtube.com/watch?v=kHb8WBtyKQg '''YouTube: Build a LightSwitch''' ]<br />
| Mike Lively of Northern Kentucky University, March 20, 2008. <br />
|}<br />
<br />
== Wiki Syntax ==<br />
<br />
Just ignore this part, I keep it for reference how to write this wiki's pages without having to edit a page to see the pothooks.<br />
<pre><br />
*Script Location<br />
<br />
User:Toady_Nakamura/Scrubber_Script<br />
<br />
<br />
*Script link in user page<br />
<br />
{{{!}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Scrubber Script|Prim Scrubber]]|Cleans memory resident functions from prim.}}<br />
{{LSL DefineRow||[[User:Toady Nakamura/Touch Toggle Light|Touch Toggle Light]]|Touch to change from dark to light.}}<br />
{{!}}}<br />
<br />
*Table format for Script Library<br />
{| class="sortable" {{Prettytable}}<br />
|- {{Hl2}}<br />
! '''Name'''<br />
! '''Creator'''<br />
! '''Description'''<br />
|-<br />
||[[User:Toady Nakamura/Scrubber Script|Script Scrubber]]<br />
||[[User:Toady Nakamura|Toady Nakamura]]<br />
||Script scrubs memory resident script functions from prim and self-deletes the script. Does not damage the prim, or remove other scripts. <br />
|-<br />
<br />
*Signing talk pages<br />
put four tildes ~~~~ and your name + UTC time is stamped for you.<br />
<br />
How to make cute *important* boxes<br />
{{KBcaution| put the text here}}<br />
</pre></div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Demo_Typecast_Random_Float_and_Integer&diff=1198827User:Toady Nakamura/Demo Typecast Random Float and Integer2016-01-11T21:42:12Z<p>Toady Nakamura: minor tweaks</p>
<hr />
<div>Demonstrates Typecasting... from float & integer to string<br />
<br />
* Floats are numbers with decimal places (3.1416 or 100.99)<br />
* Integers are round numbers (1, 3, 99, 2005)<br />
* Strings are anything enclosed in "quotes".<br />
<br />
Here we take a number (randomly picked from zero to ten) and show you how to output it as both a float and integer.<br />
<br />
That's called "type-casting"... changing one type of data to another. <br />
<br />
Put this script in a prim and poke the prim to see float values and their corresponding integer values<br />
<br />
<br />
<source lang="lsl2"><br />
default<br />
{<br />
touch_start(integer detected_index)<br />
{<br />
float number = llFrand(10.0); //pick a number between zero and the number in parenthesis<br />
<br />
string numString = (string)number; // make a string to hold the answer<br />
<br />
llOwnerSay("The float value = " + numString ); // tell owner the value as float<br />
<br />
<br />
<br />
integer numInteger = (integer)number; // convert the same number already picked<br />
<br />
numString = (string)numInteger; // to a string so it can be "said"<br />
<br />
llOwnerSay("The integer value = " + numString); // tell owner the value as integer<br />
}<br />
}<br />
</source><br />
<br />
<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Prim_Contents_Lister&diff=1198826User:Toady Nakamura/Prim Contents Lister2016-01-11T21:40:43Z<p>Toady Nakamura: notes</p>
<hr />
<div>From an [https://wiki.secondlife.com/wiki/Float_Box_Contents SL wiki entry] which lists it to hover text. <br />
*For me it's easier to use if it outputs to the local chat, so I modded it to do that & to wait after saying the contents.<br />
*If it doesn't show all the items the first time it tells you touch the box and it will keep telling!<br />
*It works better if there's not too much stuff in the box, and if the file names are not large. <br />
<br />
<br />
<source lang="lsl2"><br />
// FLOAT BOX CONTENTS -- Rolig Loon -- November 2009<br />
// //Modified Toady Nakamura 11/13/13 // Leave the header!! <br />
// Free to copy, modify, or distribute. <br />
// Please do not sell this script. Be nice.<br />
<br />
list contents = [];<br />
default<br />
{<br />
state_entry()<br />
{<br />
// this is a list of all the possible inventory types, as constants.<br />
list list_types = [INVENTORY_NONE, INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_LANDMARK,<br />
INVENTORY_CLOTHING, INVENTORY_OBJECT, INVENTORY_NOTECARD, INVENTORY_SCRIPT,<br />
INVENTORY_BODYPART, INVENTORY_ANIMATION, INVENTORY_GESTURE];<br />
<br />
// this list is of the string names corresponding to the one above.<br />
list list_names = ["None", "Texture", "Sound", "Landmark", "Clothing", "Object", "Notecard",<br />
"Script", "Body Part", "Animation", "Gesture"];<br />
<br />
integer all = llGetInventoryNumber(INVENTORY_ALL);<br />
integer i;<br />
for (i=0;i<=all-1;++i)<br />
{<br />
integer detected_type = llGetInventoryType(llGetInventoryName(INVENTORY_ALL,i)); // look up which type this object is.<br />
integer type_index = llListFindList(list_types,[detected_type]); // where in list_types is this type?<br />
string type_name = llList2String(list_names, type_index); // get the corresponding entry in the names list.<br />
contents += type_name + ": " + llGetInventoryName(INVENTORY_ALL,i) + "\n "; //Display type of content item and its name<br />
}<br />
llSetTimerEvent(1); <br />
llOwnerSay("This box lists contents when you reset the script, add or take something from contents, and / or touch the box.");<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY) // If something is added to or removed from box inventory<br />
{<br />
llResetScript();<br />
}<br />
}<br />
<br />
touch_start(integer numb)<br />
{<br />
llSetTimerEvent(1.0);<br />
}<br />
<br />
timer()<br />
{<br />
contents = llList2List(contents,1,-1) + llList2String(contents,0); // Move item 0 to the end of the list<br />
list temp = llList2List(contents,-8,-1); // Display only the last eight items <br />
llOwnerSay("THIS BOX CONTAINS: \n " + llDumpList2String(temp,""));<br />
llSetTimerEvent(0.0);<br />
}<br />
<br />
}<br />
</source><br />
<br />
<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Prim_Contents_Lister&diff=1198825User:Toady Nakamura/Prim Contents Lister2016-01-11T21:39:24Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>From an SL wiki [https://wiki.secondlife.com/wiki/Float_Box_Contents] which lists it to hover text. <br />
But it's easier to use if it outputs to the local chat, so I modded it to do that<br />
and also to wait and not repeat every 5 seconds the way he had it! <br />
<br />
If it doesn't show all the items the first time it tells you touch the box and it will keep telling!<br />
<br />
<br />
<br />
<source lang="lsl2"><br />
// FLOAT BOX CONTENTS -- Rolig Loon -- November 2009<br />
// //Modified Toady Nakamura 11/13/13 // Leave the header!! <br />
// Free to copy, modify, or distribute. <br />
// Please do not sell this script. Be nice.<br />
<br />
list contents = [];<br />
default<br />
{<br />
state_entry()<br />
{<br />
// this is a list of all the possible inventory types, as constants.<br />
list list_types = [INVENTORY_NONE, INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_LANDMARK,<br />
INVENTORY_CLOTHING, INVENTORY_OBJECT, INVENTORY_NOTECARD, INVENTORY_SCRIPT,<br />
INVENTORY_BODYPART, INVENTORY_ANIMATION, INVENTORY_GESTURE];<br />
<br />
// this list is of the string names corresponding to the one above.<br />
list list_names = ["None", "Texture", "Sound", "Landmark", "Clothing", "Object", "Notecard",<br />
"Script", "Body Part", "Animation", "Gesture"];<br />
<br />
integer all = llGetInventoryNumber(INVENTORY_ALL);<br />
integer i;<br />
for (i=0;i<=all-1;++i)<br />
{<br />
integer detected_type = llGetInventoryType(llGetInventoryName(INVENTORY_ALL,i)); // look up which type this object is.<br />
integer type_index = llListFindList(list_types,[detected_type]); // where in list_types is this type?<br />
string type_name = llList2String(list_names, type_index); // get the corresponding entry in the names list.<br />
contents += type_name + ": " + llGetInventoryName(INVENTORY_ALL,i) + "\n "; //Display type of content item and its name<br />
}<br />
llSetTimerEvent(1); <br />
llOwnerSay("This box lists contents when you reset the script, add or take something from contents, and / or touch the box.");<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY) // If something is added to or removed from box inventory<br />
{<br />
llResetScript();<br />
}<br />
}<br />
<br />
touch_start(integer numb)<br />
{<br />
llSetTimerEvent(1.0);<br />
}<br />
<br />
timer()<br />
{<br />
contents = llList2List(contents,1,-1) + llList2String(contents,0); // Move item 0 to the end of the list<br />
list temp = llList2List(contents,-8,-1); // Display only the last eight items <br />
llOwnerSay("THIS BOX CONTAINS: \n " + llDumpList2String(temp,""));<br />
llSetTimerEvent(0.0);<br />
}<br />
<br />
}<br />
</source><br />
<br />
<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Couples_Poseball&diff=1198824User:Toady Nakamura/Couples Poseball2016-01-11T21:39:01Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>Pose Balls sync script by Dora Gustafson, Studio Dora 2013<br />
*posted by [[User:Toady Nakamura|Toady Nakamura]]<br />
<br />
<br />
<br />
<source lang="lsl2"><br />
// Pose Balls sync script by Dora Gustafson, Studio Dora 2013<br />
// Free for anybody to read, copy, modify, compile, use, rip apart, trample on and flush<br />
// Build using Basic pose ball script v1.4<br />
// Will synchronize animations in two or more pose balls<br />
// All animations start when all are seated<br />
// Put the script and some animation in each pose ball<br />
// All pose balls must be linked<br />
// When one or more sitters leave all animations stop<br />
<br />
<br />
<br />
string animation;<br />
key subject;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSitTarget( <0.0, 0.0, 0.01>, ZERO_ROTATION );<br />
llSetClickAction(CLICK_ACTION_SIT);<br />
animation = llGetInventoryName( INVENTORY_ANIMATION, 0);<br />
if ( animation == "" ) animation = "sit_generic";<br />
}<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_LINK)<br />
{<br />
key sitter = llAvatarOnSitTarget() ;<br />
if ( sitter )<br />
{<br />
llSetAlpha(0.0, ALL_SIDES); // hide prim<br />
subject = sitter;<br />
}<br />
else<br />
{<br />
if ( llGetPermissions() & PERMISSION_TRIGGER_ANIMATION && llGetAgentSize(subject)!=ZERO_VECTOR) llStopAnimation(animation);<br />
llSetAlpha(1.0, ALL_SIDES); // show prim<br />
}<br />
if ((llGetNumberOfPrims() / llGetObjectPrimCount(llGetKey())) == 2) llRequestPermissions(sitter , PERMISSION_TRIGGER_ANIMATION);<br />
else if ( llGetPermissions() & PERMISSION_TRIGGER_ANIMATION && llGetAgentSize(subject)!=ZERO_VECTOR)<br />
{<br />
llStartAnimation("express_disdain");<br />
llStopAnimation(animation);<br />
}<br />
}<br />
if (change & CHANGED_INVENTORY) llResetScript();<br />
}<br />
run_time_permissions(integer perm)<br />
{<br />
if ( perm & PERMISSION_TRIGGER_ANIMATION )<br />
{<br />
llStartAnimation(animation);<br />
llStopAnimation("sit");<br />
}<br />
}<br />
on_rez(integer param) { llResetScript(); }<br />
}<br />
<br />
<br />
</source><br />
<br />
<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Smile_Script&diff=1198823User:Toady Nakamura/Smile Script2016-01-11T21:38:26Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>For humanoid avatars... this script in a prim & worn will make your avatar smile!!<br />
*Found in a 2008 freebie, modified slightly by [[User:Toady Nakamura|Toady Nakamura]]<br />
*There is a version in the LSL wiki > examples, but it's not annotated as to HOW it works<br />
<br />
<source lang="lsl2"><br />
<br />
<br />
<br />
default<br />
{<br />
state_entry()<br />
{ <br />
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);<br />
// getting permission here is automatic, because the item is worn<br />
// triggers run_time_permissions event<br />
}<br />
<br />
run_time_permissions(integer perm)<br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION)<br />
{<br />
llSetTimerEvent(5.0); <br />
// since permission was granted set a 5 second timer event<br />
}<br />
}<br />
<br />
timer()<br />
{ <br />
llStartAnimation("express_toothsmile");<br />
// every five seconds, replay the system animation<br />
}<br />
<br />
attach(key moo)<br />
{<br />
if(moo)<br />
{ <br />
llResetScript();<br />
// when the item is worn, reset the script<br />
}<br />
}<br />
}<br />
<br />
</source><br />
<br />
<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Hold_Teddy_Script&diff=1198822User:Toady Nakamura/Hold Teddy Script2016-01-11T21:37:58Z<p>Toady Nakamura: <source lang="lsl2"></p>
<hr />
<div>This script is useful for things like holding teddybears or sandwiches.<br />
*You need an animation to put in the same prim. Here I named the animation "Hold"<br />
*You have to change the animation name to the animation you include in the prim with the script. <br />
<br />
<source lang="lsl2"><br />
<br />
string anim ="Hold"; // change this name to match the animation which is in the prim !<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); <br />
// ask the owner for permission to trigger animations<br />
llStartAnimation(anim); // automatically trigger animation.<br />
}<br />
<br />
<br />
attach(key wearer)<br />
{<br />
if(wearer == NULL_KEY)<br />
{<br />
llStopAnimation(anim);<br />
llSetTimerEvent(0);<br />
}<br />
else<br />
{<br />
llRequestPermissions(wearer,PERMISSION_TRIGGER_ANIMATION);<br />
}<br />
}<br />
<br />
run_time_permissions(integer permissions)<br />
{<br />
if (PERMISSION_TRIGGER_ANIMATION & permissions)<br />
{<br />
llStartAnimation(anim);<br />
llSetTimerEvent(15);<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llStartAnimation(anim);<br />
} <br />
}<br />
<br />
</source><br />
<br />
<br />
<br />
== Credits & History ==<br />
*Script originally from a class by Minx Mousehold, modified by [[User:Toady Nakamura|Toady Nakamura]]<br />
** Modded again 08/06/12 to add state_entry after getting massive script errors - but only when worn by tinies!!<br />
<br />
== Big Scary Script Error ==<br />
<br />
Here's the script error that you get if you don't have that state entry in the script & you're tiny <br />
*''Script trying to stop animations but PERMISSION_TRIGGER_ANIMATION permission not set''<br />
<br />
Because ... although the PERMISSION_TRIGGER_ANIMATION permission is automatically granted when sitting, a prior call to llRequestPermissions is required! (Thank you [http://lslwiki.net/lslwiki/wakka.php?wakka=llStartAnimation wiki_wakka!])<br />
<br />
==More? ==<br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamurahttps://wiki.secondlife.com/w/index.php?title=User:Toady_Nakamura/Landmark_Giver_and_Counter&diff=1198821User:Toady Nakamura/Landmark Giver and Counter2016-01-11T21:36:25Z<p>Toady Nakamura: fill in template</p>
<hr />
<div>*Put one Landmark in Prim Contents, then put this script inside. <br />
*If you do it the other way, hit "reset script" to be sure it finds the landmark<br />
*Gives the landmark to anyone not owner<br />
*Tells owner how many landmarks have been gifted.<br />
<br />
<br />
<source lang="lsl2"><br />
integer gifts = 0; // sets initial value to zero<br />
<br />
default<br />
{<br />
on_rez(integer start_param)<br />
{<br />
llResetScript(); // this resets whenever the prim is brought from inventory<br />
}<br />
<br />
state_entry()<br />
{ <br />
llSetText( "Touch for a Landmark", <1.0, 1.0, 1.0>, 1.0);<br />
//sets the hover text "message", color (here white), and intensity (can be zero to 1.0)<br />
}<br />
<br />
touch_start(integer total_number)<br />
{<br />
if ( llDetectedKey(0) != llGetOwner() )// if the toucher is NOT the owner (!=)<br />
{<br />
gifts = gifts++; // count up one from previous value<br />
llGiveInventory(llDetectedKey(0), llGetInventoryName(INVENTORY_LANDMARK, 0));<br />
}<br />
else if ( llDetectedKey(0) == llGetOwner() ) // if the toucher IS the owner (==)<br />
{<br />
llOwnerSay((string)gifts + " people have gotten landmarks from me!");<br />
}<br />
}<br />
}<br />
</source><br />
Visit my LSL wiki page for my library of simple scripts ! [[User:Toady Nakamura|Toady Nakamura]]</div>Toady Nakamura