<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=GP+Runo</id>
	<title>Second Life Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=GP+Runo"/>
	<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/wiki/Special:Contributions/GP_Runo"/>
	<updated>2026-06-06T21:44:42Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlOnRegionReset&amp;diff=22737</id>
		<title>LlOnRegionReset</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlOnRegionReset&amp;diff=22737"/>
		<updated>2007-06-06T08:23:29Z</updated>

		<summary type="html">&lt;p&gt;GP Runo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It would be nice if a shutdown notice from LL would trigger a scripted event. I&#039;m using userlists which get lost when the region resets. If a noticed regionreset will trigger an event, it would be possible to take backup measures using httpreq.&lt;br /&gt;
&lt;br /&gt;
Like the event will be set with LlSetResetEvent(integer secondstodisaster);&lt;br /&gt;
&lt;br /&gt;
ResetEvent(string LLNotice) {&lt;br /&gt;
llHTTPreq(migratedate(ALL));&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>GP Runo</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlOnRegionReset&amp;diff=22066</id>
		<title>LlOnRegionReset</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlOnRegionReset&amp;diff=22066"/>
		<updated>2007-05-29T22:33:33Z</updated>

		<summary type="html">&lt;p&gt;GP Runo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It would be nice to have a scripted notice, when Linden Labs decides to reset all regions.&lt;br /&gt;
I&#039;m using userlists which get lost when the region resets. If a noticed regionreset will trigger an event, it would&lt;br /&gt;
be possible to take backup measures using httpreq.&lt;/div&gt;</summary>
		<author><name>GP Runo</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Useful_Function_WishList&amp;diff=22065</id>
		<title>LSL Useful Function WishList</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Useful_Function_WishList&amp;diff=22065"/>
		<updated>2007-05-29T22:31:37Z</updated>

		<summary type="html">&lt;p&gt;GP Runo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{LSL Header}}&lt;br /&gt;
==A==&lt;br /&gt;
[[llAddToEstateBanList]]&lt;br /&gt;
==C==&lt;br /&gt;
[[llChangeLandPassPrice]]&lt;br /&gt;
&lt;br /&gt;
To allow the access price to enter a parcel of land to be changed via a script.&lt;br /&gt;
&lt;br /&gt;
==E==&lt;br /&gt;
{{LSLG|llExecuteMenuCommand}}&lt;br /&gt;
&lt;br /&gt;
==F==&lt;br /&gt;
{{LSLG|llFrandom}}&lt;br /&gt;
&lt;br /&gt;
==G==&lt;br /&gt;
{{LSLG|llGetParcelBanList}}&lt;br /&gt;
{{LSLG|llGetEstateBanList}}&lt;br /&gt;
{{LSLG|llGetAvatarKeysOnParcel}}&lt;br /&gt;
{{LSLG|llGetAvatarKeysOnEstate}}&lt;br /&gt;
{{LSLG|llGetMyAccountBalance}}&lt;br /&gt;
{{LSLG|llGetGroup}}&lt;br /&gt;
&amp;lt;s&amp;gt;llGetScriptCreatorKey&amp;lt;/s&amp;gt; - use [[llGetInventoryCreator]]([[llGetScriptName]]()) instead&lt;br /&gt;
{{LSLG|llGetRegionPopulation}}&lt;br /&gt;
{{LSLG|llGetParcelPopulation}}&lt;br /&gt;
{{LSLG|llGetWorldPopulation}}&lt;br /&gt;
{{LSLG|llGetPrice}}&lt;br /&gt;
{{LSLG|llGetAgentPreferedLanguage}}&lt;br /&gt;
&lt;br /&gt;
==I==&lt;br /&gt;
{{LSLG|llInstantMessageGroup}}&lt;br /&gt;
{{LSLG|llInviteToGroup}}&lt;br /&gt;
==L==&lt;br /&gt;
{{LSLG|llLBETMB}}&lt;br /&gt;
==N==&lt;br /&gt;
{{LSLG|llName2Key}}&lt;br /&gt;
&lt;br /&gt;
==O==&lt;br /&gt;
{{LSLG|llOnRegionReset}}&lt;br /&gt;
&lt;br /&gt;
==P==&lt;br /&gt;
{{LSLG|llPizza}}&lt;br /&gt;
{{LSLG|position_change}}&lt;br /&gt;
&lt;br /&gt;
==R==&lt;br /&gt;
{{LSLG|llRaiseError}}&lt;br /&gt;
{{LSLG|llRemoveFromEstateBanList}}&lt;br /&gt;
{{LSLG|llReturnObject}}&lt;br /&gt;
{{LSLG|llReturnOwnersObjects}}&lt;br /&gt;
{{LSLG|llRotateAgent}}&lt;br /&gt;
&lt;br /&gt;
==S==&lt;br /&gt;
{{LSLG|llSoundex}}&lt;br /&gt;
{{LSLG|llSpeakText}}&lt;br /&gt;
{{LSLG|llSpeech2Text}}&lt;br /&gt;
{{LSLG|llSpeech2TextRemove}}&lt;br /&gt;
{{LSLG|llSayWithinRange}}&lt;br /&gt;
&lt;br /&gt;
==T==&lt;br /&gt;
{{LSLG|llTeleportAgent}}&lt;br /&gt;
{{LSLG|llTriggerLandmark}}&lt;br /&gt;
{{LSLG|llTrackTouches}}&lt;br /&gt;
&lt;br /&gt;
==Other functionality==&lt;br /&gt;
{{LSLG|Block comments}}&lt;br /&gt;
{{LSLG|True tab-stops}}&lt;br /&gt;
{{LSLG|Code Folding}}&lt;br /&gt;
{{LSLG|Windowed Scripting}}&lt;br /&gt;
{{LSLG|Switch Statement}}&lt;br /&gt;
{{LSLG|Array}}&lt;br /&gt;
{{LSLG|on_unrez|Event: Unrez / Delete}}&lt;br /&gt;
{{LSLG|Conditionals}}&lt;br /&gt;
{{LSLG|State variables}}&lt;/div&gt;</summary>
		<author><name>GP Runo</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=XyzzyText&amp;diff=21510</id>
		<title>XyzzyText</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=XyzzyText&amp;diff=21510"/>
		<updated>2007-05-24T15:47:58Z</updated>

		<summary type="html">&lt;p&gt;GP Runo: I added a short and quick howto for noobs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;XyzzyText is a new version of Xytext with some advanced features:&lt;br /&gt;
&lt;br /&gt;
* Efficiency!  You can now control an entire linkset with just one script.&lt;br /&gt;
* Flexible Speed vs Lag.  Just drop in plug-and-play slave scripts to increase rendering speed.  (More than 4-5 slaves not recommended, there is diminishing returns)&lt;br /&gt;
* Ease of use.  There is no need to know link numbers.  Simply name the child prims xyzzytext-banknumber-cellnumber.&lt;br /&gt;
* To use, pass the bank number to use in the &amp;quot;key&amp;quot; field of the link message of DISPLAY_STRING/EXTENDED.&lt;br /&gt;
&lt;br /&gt;
* Gigs Taggart hereby releases his contributions to this under the MIT license.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Display Prims named: &lt;br /&gt;
xyzzytext-0-0 xyzzytext-0-1&lt;br /&gt;
xyzzytext-1-0 xyzzytext-1-1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quickstart:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* Store all scripts in your inventory&lt;br /&gt;
* Rezz a box&lt;br /&gt;
* Drop the prim setup script in it (You now have one unit, name it xyzzytext-0-0)&lt;br /&gt;
* Make a row of four of these prims (xyzzytext-0-0 xyzzytext-0-1,xyzzytext-0-2,xyzzytext-0-3)&lt;br /&gt;
* Move a copy of this row a little down, and rename the new row(xyzzytext-1-0 xyzzytext-1-1,xyzzytext-1-2,xyzzytext-1-3)&lt;br /&gt;
* Do this for every row you make&lt;br /&gt;
* Create a big box that serves as the board-background(mainprim)&lt;br /&gt;
* Copy the mainscript and usage script in it&lt;br /&gt;
* Link all prims with the mainprim(selected last), so the mainprim keeps yellow after linking(root-prim)&lt;br /&gt;
* Type something, and check if it all works&lt;br /&gt;
* Flatten the prims, so the text looks straight&lt;br /&gt;
* Consider adding slavescripts to the mainprim if you have alot of rows&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer DISPLAY_STRING      = 204000; &lt;br /&gt;
integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003; &lt;br /&gt;
integer SET_FADE_OPTIONS    = 204004; &lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
integer SET_COLOR           = 204007; &lt;br /&gt;
integer RESCAN_LINKSET      = 204008;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer gToggle;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0,&amp;quot;&amp;quot;,NULL_KEY,&amp;quot;&amp;quot;);&lt;br /&gt;
       &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel,string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        if (gToggle)&lt;br /&gt;
            llMessageLinked(LINK_THIS,DISPLAY_STRING,name + &amp;quot;:&amp;quot;+ message,&amp;quot;0&amp;quot;);&lt;br /&gt;
        else&lt;br /&gt;
            llMessageLinked(LINK_THIS,DISPLAY_STRING,name + &amp;quot;:&amp;quot;+ message,&amp;quot;1&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        gToggle=!gToggle;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Main Script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
// XyzzyText v2.0 Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Heavily Modified by Thraxis Epsilon and Gigs Taggart 5/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation w/ optional slaves&lt;br /&gt;
// Enable prim-label functionality&lt;br /&gt;
// Enabled Banking&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Core XyText Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
/////////////// CONSTANTS /////////////////// &lt;br /&gt;
// XyText Message Map. &lt;br /&gt;
integer DISPLAY_STRING      = 204000; &lt;br /&gt;
integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003; &lt;br /&gt;
integer SET_FADE_OPTIONS    = 204004; &lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
integer SET_COLOR           = 204007; &lt;br /&gt;
integer RESCAN_LINKSET      = 204008;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET = 205005;&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence. &lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character. &lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;12345&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1; &lt;br /&gt;
&lt;br /&gt;
// Used to hide the text after a fade-out. &lt;br /&gt;
key     TRANSPARENT     = &amp;quot;701917a8-d614-471f-13dd-5f4644e36e3c&amp;quot;; &lt;br /&gt;
///////////// END CONSTANTS //////////////// &lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES /////////////// &lt;br /&gt;
// This is the key of the font we are displaying. &lt;br /&gt;
key     gFontTexture        = &amp;quot;b2e7394f-5e54-aa12-6e1c-ef327b6bed9e&amp;quot;; &lt;br /&gt;
// All displayable characters.  Default to ASCII order. &lt;br /&gt;
string gCharIndex; &lt;br /&gt;
&lt;br /&gt;
// This is whether or not to use the fade in/out special effect. &lt;br /&gt;
integer gCellUseFading      = FALSE; &lt;br /&gt;
// This is how long to display the text before fading out (if using &lt;br /&gt;
// fading special effect). &lt;br /&gt;
// Note: &amp;lt; 0  means don&#039;t fade out. &lt;br /&gt;
float   gCellHoldDelay      = 1.0; &lt;br /&gt;
&lt;br /&gt;
integer gSlaveRegistered;&lt;br /&gt;
list gSlaveNames;&lt;br /&gt;
&lt;br /&gt;
integer BANK_STRIDE=3; //offset, length, highest_dirty&lt;br /&gt;
list gBankingData;&lt;br /&gt;
&lt;br /&gt;
/////////// END GLOBAL VARIABLES //////////// &lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
   gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(integer index) { &lt;br /&gt;
   // Calculate the offset needed to display this character. &lt;br /&gt;
   integer Row = index / 10; &lt;br /&gt;
   integer Col = index % 10; &lt;br /&gt;
&lt;br /&gt;
   // Return the offset in the texture. &lt;br /&gt;
   return &amp;lt;-0.45 + 0.1 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_offset1, vector grid_offset2, vector grid_offset3, vector grid_offset4, vector grid_offset5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
    &lt;br /&gt;
   // &amp;lt;-0.256, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0.130, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;-0.74, 0, 0&amp;gt; &lt;br /&gt;
    &lt;br /&gt;
   llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset1 + &amp;lt;0.037, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset2, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, (string)gFontTexture, &amp;lt;-0.74, 0.1, 0&amp;gt;, grid_offset3 - &amp;lt;0.244, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset4, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset5 - &amp;lt;0.037, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) { &lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderWithEffects(integer link, string str) { &lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // First set the alpha to the lowest possible. &lt;br /&gt;
   llSetLinkAlpha(link,0.05, ALL_SIDES); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5);          // Now turn up the alpha until it is at full strength. &lt;br /&gt;
    float Alpha; &lt;br /&gt;
    for (Alpha = 0.10; Alpha &amp;lt;= 1.0; Alpha += 0.05) &lt;br /&gt;
       llSetLinkAlpha(link,Alpha, ALL_SIDES); &lt;br /&gt;
          // See if we want to fade out as well. &lt;br /&gt;
   if (gCellHoldDelay &amp;lt; 0.0) &lt;br /&gt;
       // No, bail out. (Just keep showing the string at full strength). &lt;br /&gt;
       return; &lt;br /&gt;
          // Hold the text for a while. &lt;br /&gt;
   llSleep(gCellHoldDelay); &lt;br /&gt;
      // Now fade out. &lt;br /&gt;
   for (Alpha = 0.95; Alpha &amp;gt;= 0.05; Alpha -= 0.05) &lt;br /&gt;
       llSetLinkAlpha(link,Alpha, ALL_SIDES); &lt;br /&gt;
          // Make the text transparent to fully hide it. &lt;br /&gt;
   llSetLinkTexture(link,TRANSPARENT, ALL_SIDES); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer RenderExtended(integer link, string str, integer render) {&lt;br /&gt;
   // Look for escape sequences. &lt;br /&gt;
   integer length = 0;&lt;br /&gt;
   list Parsed       = llParseString2List(str, [], [ESCAPE_SEQUENCE]); &lt;br /&gt;
   integer ParsedLen = llGetListLength(Parsed); &lt;br /&gt;
&lt;br /&gt;
   // Create a list of index values to work with. &lt;br /&gt;
   list Indices; &lt;br /&gt;
   // We start with room for 5 indices. &lt;br /&gt;
   integer IndicesLeft = 5; &lt;br /&gt;
&lt;br /&gt;
   integer i; &lt;br /&gt;
   string Token; &lt;br /&gt;
   integer Clipped; &lt;br /&gt;
   integer LastWasEscapeSequence = FALSE; &lt;br /&gt;
   // Work from left to right. &lt;br /&gt;
   for (i = 0; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; i++) { &lt;br /&gt;
       Token = llList2String(Parsed, i); &lt;br /&gt;
&lt;br /&gt;
       // If this is an escape sequence, just set the flag and move on. &lt;br /&gt;
       if (Token == ESCAPE_SEQUENCE) { &lt;br /&gt;
           LastWasEscapeSequence = TRUE; &lt;br /&gt;
       } &lt;br /&gt;
       else { // Token != ESCAPE_SEQUENCE &lt;br /&gt;
           // Otherwise this is a normal token.  Check its length. &lt;br /&gt;
           Clipped = FALSE; &lt;br /&gt;
           integer TokenLength = llStringLength(Token); &lt;br /&gt;
           // Clip if necessary. &lt;br /&gt;
           if (TokenLength &amp;gt; IndicesLeft) { &lt;br /&gt;
               Token = llGetSubString(Token, 0, IndicesLeft - 1); &lt;br /&gt;
               TokenLength = llStringLength(Token); &lt;br /&gt;
               IndicesLeft = 0; &lt;br /&gt;
               Clipped = TRUE; &lt;br /&gt;
           } &lt;br /&gt;
           else &lt;br /&gt;
               IndicesLeft -= TokenLength; &lt;br /&gt;
&lt;br /&gt;
           // Was the previous token an escape sequence? &lt;br /&gt;
           if (LastWasEscapeSequence) { &lt;br /&gt;
               // Yes, the first character is an escape character, the rest are normal. &lt;br /&gt;
               length += 3;&lt;br /&gt;
               // This is the extended character. &lt;br /&gt;
               if(render)               &lt;br /&gt;
                    Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95]; &lt;br /&gt;
&lt;br /&gt;
               // These are the normal characters.&lt;br /&gt;
               length+=TokenLength - 1; &lt;br /&gt;
               if(render)&lt;br /&gt;
               {&lt;br /&gt;
                  integer j; &lt;br /&gt;
                   for (j = 1; j &amp;lt; TokenLength; j++) &lt;br /&gt;
                   {&lt;br /&gt;
                       Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))]; &lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
           } &lt;br /&gt;
           else { // Normal string. &lt;br /&gt;
               // Just add the characters normally. &lt;br /&gt;
               length+=TokenLength;&lt;br /&gt;
               if(render)&lt;br /&gt;
               {               &lt;br /&gt;
                   integer j; &lt;br /&gt;
                   for (j = 0; j &amp;lt; TokenLength; j++) &lt;br /&gt;
                   {                  &lt;br /&gt;
                       Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                   }&lt;br /&gt;
                }&lt;br /&gt;
           } &lt;br /&gt;
&lt;br /&gt;
           // Unset this flag, since this was not an escape sequence. &lt;br /&gt;
           LastWasEscapeSequence = FALSE; &lt;br /&gt;
       } &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   // Use the indices to create grid positions.&lt;br /&gt;
  if(render)&lt;br /&gt;
  {   &lt;br /&gt;
       vector GridOffset1 = GetGridOffset( llList2Integer(Indices, 0) ); &lt;br /&gt;
       vector GridOffset2 = GetGridOffset( llList2Integer(Indices, 1) ); &lt;br /&gt;
       vector GridOffset3 = GetGridOffset( llList2Integer(Indices, 2) ); &lt;br /&gt;
       vector GridOffset4 = GetGridOffset( llList2Integer(Indices, 3) ); &lt;br /&gt;
       vector GridOffset5 = GetGridOffset( llList2Integer(Indices, 4) ); &lt;br /&gt;
    &lt;br /&gt;
       // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
       ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5);&lt;br /&gt;
   }&lt;br /&gt;
   return length;&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) { &lt;br /&gt;
   // This converts from an ASCII based index to our indexing scheme. &lt;br /&gt;
   if (index &amp;gt;= 32) // &#039; &#039; or higher &lt;br /&gt;
       index -= 32; &lt;br /&gt;
   else { // index &amp;lt; 32 &lt;br /&gt;
       // Quick bounds check. &lt;br /&gt;
       if (index &amp;gt; 15) &lt;br /&gt;
           index = 15; &lt;br /&gt;
&lt;br /&gt;
       index += 94; // extended characters &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   return index; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PassToRender(integer render,string message, integer bank)&lt;br /&gt;
{&lt;br /&gt;
    float time;&lt;br /&gt;
    integer extendedlen = 0;&lt;br /&gt;
    integer link;&lt;br /&gt;
    integer x;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    integer msgLen = llStringLength(message);&lt;br /&gt;
    string TextToRender;&lt;br /&gt;
    integer num_slaves=llGetListLength(gSlaveNames);&lt;br /&gt;
    string slave_name; //avoids unnecessary casts, keeping it as a string&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer bank_offset=llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_length=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
    integer bank_highest_dirty=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
    &lt;br /&gt;
    for (x=0;x &amp;lt; msgLen;x = x + 5)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        if (i &amp;gt;= bank_length)  //we don&#039;t want to run off the end of the bank&lt;br /&gt;
        {&lt;br /&gt;
            //set the dirty to max, and bail out, we&#039;re done&lt;br /&gt;
            gBankingData=llListReplaceList(gBankingData, [bank_length], (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
            return;&lt;br /&gt;
        }   &lt;br /&gt;
        &lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        TextToRender = llGetSubString(message, x, x + 15);&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves +1) != 0))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
               llMessageLinked(LINK_THIS, SLAVE_DISPLAY, TextToRender, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                //time = llGetAndResetTime();&lt;br /&gt;
                if(llSubStringIndex(TextToRender,&amp;quot;\e&amp;quot;) &amp;gt; x)&lt;br /&gt;
                    extendedlen = 5;&lt;br /&gt;
                else&lt;br /&gt;
                    extendedlen = RenderExtended(link,TextToRender,0);&lt;br /&gt;
                if (extendedlen &amp;gt; 5)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen - 5;&lt;br /&gt;
                }&lt;br /&gt;
               llMessageLinked(LINK_THIS, SLAVE_DISPLAY_EXTENDED, TextToRender, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));&lt;br /&gt;
              // llOwnerSay((string)llGetAndResetTime());&lt;br /&gt;
            }&lt;br /&gt;
               //sorry, no fade effect with slave&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
                RenderString(link,TextToRender);&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                extendedlen = RenderExtended(link,TextToRender,1);&lt;br /&gt;
                if (extendedlen &amp;gt; 5)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen - 5;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
            }&lt;br /&gt;
            if (render == 3)&lt;br /&gt;
                RenderWithEffects(link,TextToRender);&lt;br /&gt;
        }&lt;br /&gt;
        i=i+1;            &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (bank_highest_dirty==0)&lt;br /&gt;
        bank_highest_dirty=bank_length;&lt;br /&gt;
    &lt;br /&gt;
    integer current_highest_dirty=i;&lt;br /&gt;
    while (i &amp;lt; bank_highest_dirty)&lt;br /&gt;
    {&lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves+1) != 0))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_DISPLAY, &amp;quot;     &amp;quot;, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));       &lt;br /&gt;
            //sorry, no fade effect with slave&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            RenderString(link,&amp;quot;     &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        i=i+1;        &lt;br /&gt;
    }&lt;br /&gt;
    gBankingData=llListReplaceList(gBankingData, [current_highest_dirty], (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Bitwise Voodoo by Gigs Taggart&lt;br /&gt;
list gXyTextPrims;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer get_number_of_prims()&lt;br /&gt;
{//ignores avatars.&lt;br /&gt;
    integer a = llGetNumberOfPrims();&lt;br /&gt;
    if(1 &amp;lt; a)&lt;br /&gt;
        while(llGetAgentSize(llGetLinkKey(a)))&lt;br /&gt;
            --a;&lt;br /&gt;
    return a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//functions to pack 8-bit shorts into ints&lt;br /&gt;
list pack_and_insert(list in_list, integer pos, integer value)&lt;br /&gt;
{&lt;br /&gt;
    //figure out the bitpack position&lt;br /&gt;
    integer pack=pos%4; //4 bytes per int&lt;br /&gt;
    pos=pos/4;&lt;br /&gt;
    integer shifted=value &amp;lt;&amp;lt; (pack * 8);&lt;br /&gt;
    integer old_value=llList2Integer(in_list, pos);&lt;br /&gt;
    shifted=old_value | shifted;&lt;br /&gt;
    in_list = llListReplaceList(in_list, [ shifted ], pos, pos);&lt;br /&gt;
    return in_list;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer unpack(list in_list, integer pos)&lt;br /&gt;
{&lt;br /&gt;
    integer pack=pos%4;&lt;br /&gt;
    pos=pos/4;&lt;br /&gt;
    integer value=llList2Integer(in_list, pos);&lt;br /&gt;
    return value &amp;gt;&amp;gt; (pack * 8) &amp;amp; 0x000000FF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
change_color(vector color)&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=llGetListLength(gXyTextPrims);&lt;br /&gt;
    num_prims=num_prims*4;&lt;br /&gt;
    &lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i=0;i&amp;lt;=num_prims;i++)&lt;br /&gt;
    {&lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (link==0)&lt;br /&gt;
            return;&lt;br /&gt;
            &lt;br /&gt;
            &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
        PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
        PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
        PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
        PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
        PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]); &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
init()&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=get_number_of_prims();&lt;br /&gt;
    integer x;&lt;br /&gt;
    string link_name;&lt;br /&gt;
    integer bank=0;&lt;br /&gt;
    integer bank_empty=FALSE;&lt;br /&gt;
    integer prims_pointer=0; //&amp;quot;pointer&amp;quot; to the next entry to be used in the gXyTextPrims list.&lt;br /&gt;
    &lt;br /&gt;
    list temp_bank;&lt;br /&gt;
    integer temp_bank_stride=2;&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    //FIXME: font texture might should be per-bank&lt;br /&gt;
    llMessageLinked(LINK_THIS, SET_FONT_TEXTURE, &amp;quot;&amp;quot; ,gFontTexture);&lt;br /&gt;
    &lt;br /&gt;
    gXyTextPrims=[];&lt;br /&gt;
    for (x=0;x&amp;lt;64;x++)&lt;br /&gt;
    {&lt;br /&gt;
        gXyTextPrims= (gXyTextPrims = []) + gXyTextPrims + [0];  //we need to pad out the list to make it easier to add things in any order later&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    while(!bank_empty)&lt;br /&gt;
    {&lt;br /&gt;
        bank_empty=TRUE;&lt;br /&gt;
        &lt;br /&gt;
        //loop over all prims, looking for ones in the current bank&lt;br /&gt;
        for(x=0;x&amp;lt;=num_prims;x++)&lt;br /&gt;
        {&lt;br /&gt;
            link_name=llGetLinkName(x);&lt;br /&gt;
            list tmp = llParseString2List(link_name, [&amp;quot;-&amp;quot;], []);&lt;br /&gt;
            string xyzzytext = llList2String(tmp,0);&lt;br /&gt;
            if(xyzzytext == &amp;quot;xyzzytext&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                integer prims_bank=llList2Integer(tmp,1);&lt;br /&gt;
                if (prims_bank==bank)&lt;br /&gt;
                {&lt;br /&gt;
                    bank_empty=FALSE;&lt;br /&gt;
                    integer pos=llList2Integer(tmp,2);&lt;br /&gt;
                    temp_bank+=[pos];&lt;br /&gt;
                    temp_bank+=[x];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if (!bank_empty)&lt;br /&gt;
        {&lt;br /&gt;
            //sort the current bank&lt;br /&gt;
            temp_bank=llListSort(temp_bank, temp_bank_stride, TRUE);&lt;br /&gt;
            &lt;br /&gt;
            integer y;&lt;br /&gt;
            integer temp_len=llGetListLength(temp_bank);&lt;br /&gt;
            &lt;br /&gt;
            //store metadata&lt;br /&gt;
            gBankingData+=[prims_pointer];&lt;br /&gt;
            gBankingData+=[temp_len/temp_bank_stride];&lt;br /&gt;
            gBankingData+=[0];&lt;br /&gt;
            &lt;br /&gt;
            //repack the bank into the prim list&lt;br /&gt;
            for (y=0; y &amp;lt; temp_len; y+=temp_bank_stride)&lt;br /&gt;
            {&lt;br /&gt;
                gXyTextPrims = pack_and_insert(gXyTextPrims, prims_pointer, llList2Integer(temp_bank, y+1));&lt;br /&gt;
                prims_pointer++;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        temp_bank=[];        &lt;br /&gt;
        bank++;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llMessageLinked(LINK_THIS, SLAVE_RESET, &amp;quot;&amp;quot; , NULL_KEY);&lt;br /&gt;
    //llOwnerSay((string)llGetFreeMemory());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default { &lt;br /&gt;
   state_entry() { &lt;br /&gt;
       // Initialize the character index. &lt;br /&gt;
       ResetCharIndex();&lt;br /&gt;
       init();&lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   on_rez(integer num)&lt;br /&gt;
   {&lt;br /&gt;
      llResetScript();       &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   link_message(integer sender, integer channel, string data, key id) { &lt;br /&gt;
        if (id==NULL_KEY)&lt;br /&gt;
            id=&amp;quot;0&amp;quot;;&lt;br /&gt;
            &lt;br /&gt;
        if (channel == DISPLAY_STRING) { &lt;br /&gt;
           PassToRender(1,data, (integer)((string)id)); &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        if (channel == DISPLAY_EXTENDED) { &lt;br /&gt;
           PassToRender(2,data, (integer)((string)id)); &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        if (channel == REMAP_INDICES) { &lt;br /&gt;
           // Parse the message, splitting it up into index values. &lt;br /&gt;
           list Parsed = llCSV2List(data); &lt;br /&gt;
           integer i; &lt;br /&gt;
           // Go through the list and swap each pair of indices. &lt;br /&gt;
           for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) { &lt;br /&gt;
               integer Index1 = ConvertIndex( llList2Integer(Parsed, i) ); &lt;br /&gt;
               integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) ); &lt;br /&gt;
        &lt;br /&gt;
               // Swap these index values. &lt;br /&gt;
               string Value1 = llGetSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
               string Value2 = llGetSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
        &lt;br /&gt;
               gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
               gCharIndex = llInsertString(gCharIndex, Index1, Value2); &lt;br /&gt;
        &lt;br /&gt;
               gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
               gCharIndex = llInsertString(gCharIndex, Index2, Value1); &lt;br /&gt;
           } &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        &lt;br /&gt;
        if (channel == RESCAN_LINKSET)&lt;br /&gt;
        {&lt;br /&gt;
            init();&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (channel == RESET_INDICES) { &lt;br /&gt;
           // Restore the character index back to default settings. &lt;br /&gt;
           ResetCharIndex(); &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        if (channel == SET_FADE_OPTIONS) { &lt;br /&gt;
           // Change the channel we listen to for cell commands, the &lt;br /&gt;
           // starting character position to extract from, and &lt;br /&gt;
           // special effect attributes. &lt;br /&gt;
           list Parsed = llCSV2List(data); &lt;br /&gt;
           gCellUseFading      = (integer) llList2String(Parsed, 0); &lt;br /&gt;
           gCellHoldDelay      = (float)   llList2String(Parsed, 1); &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        if (channel == SET_FONT_TEXTURE) { &lt;br /&gt;
           // Use the new texture instead of the current one. &lt;br /&gt;
           gFontTexture = id; &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        if (channel == SET_COLOR) { &lt;br /&gt;
           vector newColor = (vector)data; &lt;br /&gt;
           change_color(newColor); &lt;br /&gt;
        } &lt;br /&gt;
       &lt;br /&gt;
        if (channel == REGISTER_SLAVE)&lt;br /&gt;
        {&lt;br /&gt;
            if(~llListFindList(gSlaveNames, [data]))&lt;br /&gt;
            {//it already exists&lt;br /&gt;
                llMessageLinked(LINK_THIS, SLAVE_RECOGNIZED, data , NULL_KEY);&lt;br /&gt;
                //llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave, Existing Slave Recognized: &amp;quot; + data);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            gSlaveNames+=[data];&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_RECOGNIZED, data , NULL_KEY);&lt;br /&gt;
            gSlaveRegistered=TRUE;&lt;br /&gt;
            //llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave(s) Recognized: &amp;quot; + data);&lt;br /&gt;
        }&lt;br /&gt;
   } &lt;br /&gt;
   &lt;br /&gt;
   &lt;br /&gt;
    changed(integer change)&lt;br /&gt;
    {&lt;br /&gt;
        if(change&amp;amp;CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            if(!gSlaveRegistered)        &lt;br /&gt;
                return;&lt;br /&gt;
        &lt;br /&gt;
           &lt;br /&gt;
            integer num_slaves=llGetListLength(gSlaveNames);&lt;br /&gt;
&lt;br /&gt;
            integer x;&lt;br /&gt;
            for (x=0;x&amp;lt;num_slaves;x++)&lt;br /&gt;
            {&lt;br /&gt;
                if ((llGetInventoryType(llList2String(gSlaveNames, x)) == -1)&amp;amp;&amp;amp;(x&amp;lt;llGetListLength(gSlaveNames)))&lt;br /&gt;
                {&lt;br /&gt;
                    //llOwnerSay(&amp;quot;Slave Removed: &amp;quot; + llList2String(gSlaveNames, x));&lt;br /&gt;
                    gSlaveNames = llDeleteSubList(gSlaveNames, x, x);&lt;br /&gt;
                    x--;//our indices shifted&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Slave Script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
// XyText v2.0 SLAVE Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon and Gigs Taggart 5/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003;&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET = 205005;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence. &lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character. &lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;12345&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES /////////////// &lt;br /&gt;
// This is the key of the font we are displaying. &lt;br /&gt;
key     gFontTexture        = &amp;quot;b2e7394f-5e54-aa12-6e1c-ef327b6bed9e&amp;quot;; &lt;br /&gt;
// All displayable characters.  Default to ASCII order. &lt;br /&gt;
string gCharIndex; &lt;br /&gt;
&lt;br /&gt;
integer gActive; //if we are recognized, this is true&lt;br /&gt;
/////////// END GLOBAL VARIABLES //////////// &lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
   gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(integer index) { &lt;br /&gt;
   // Calculate the offset needed to display this character. &lt;br /&gt;
   integer Row = index / 10; &lt;br /&gt;
   integer Col = index % 10; &lt;br /&gt;
&lt;br /&gt;
   // Return the offset in the texture. &lt;br /&gt;
   return &amp;lt;-0.45 + 0.1 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_offset1, vector grid_offset2, vector grid_offset3, vector grid_offset4, vector grid_offset5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
    &lt;br /&gt;
   // &amp;lt;-0.256, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0.130, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;-0.74, 0, 0&amp;gt; &lt;br /&gt;
    &lt;br /&gt;
   llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset1 + &amp;lt;0.037, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset2, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, (string)gFontTexture, &amp;lt;-0.74, 0.1, 0&amp;gt;, grid_offset3 - &amp;lt;0.244, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset4, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset5 - &amp;lt;0.037, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) {&lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderExtended(integer link, string str) { &lt;br /&gt;
   // Look for escape sequences. &lt;br /&gt;
   list Parsed       = llParseString2List(str, [], [ESCAPE_SEQUENCE]); &lt;br /&gt;
   integer ParsedLen = llGetListLength(Parsed); &lt;br /&gt;
&lt;br /&gt;
   // Create a list of index values to work with. &lt;br /&gt;
   list Indices; &lt;br /&gt;
   // We start with room for 5 indices. &lt;br /&gt;
   integer IndicesLeft = 5; &lt;br /&gt;
&lt;br /&gt;
   integer i; &lt;br /&gt;
   string Token; &lt;br /&gt;
   integer Clipped; &lt;br /&gt;
   integer LastWasEscapeSequence = FALSE; &lt;br /&gt;
   // Work from left to right. &lt;br /&gt;
   for (i = 0; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; i++) { &lt;br /&gt;
       Token = llList2String(Parsed, i); &lt;br /&gt;
&lt;br /&gt;
       // If this is an escape sequence, just set the flag and move on. &lt;br /&gt;
       if (Token == ESCAPE_SEQUENCE) { &lt;br /&gt;
           LastWasEscapeSequence = TRUE; &lt;br /&gt;
       } &lt;br /&gt;
       else { // Token != ESCAPE_SEQUENCE &lt;br /&gt;
           // Otherwise this is a normal token.  Check its length. &lt;br /&gt;
           Clipped = FALSE; &lt;br /&gt;
           integer TokenLength = llStringLength(Token); &lt;br /&gt;
           // Clip if necessary. &lt;br /&gt;
           if (TokenLength &amp;gt; IndicesLeft) { &lt;br /&gt;
               Token = llGetSubString(Token, 0, IndicesLeft - 1); &lt;br /&gt;
               TokenLength = llStringLength(Token); &lt;br /&gt;
               IndicesLeft = 0; &lt;br /&gt;
               Clipped = TRUE; &lt;br /&gt;
           } &lt;br /&gt;
           else &lt;br /&gt;
               IndicesLeft -= TokenLength; &lt;br /&gt;
&lt;br /&gt;
           // Was the previous token an escape sequence? &lt;br /&gt;
           if (LastWasEscapeSequence) { &lt;br /&gt;
               // Yes, the first character is an escape character, the rest are normal. &lt;br /&gt;
&lt;br /&gt;
               // This is the extended character. &lt;br /&gt;
               Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95]; &lt;br /&gt;
&lt;br /&gt;
               // These are the normal characters. &lt;br /&gt;
               integer j; &lt;br /&gt;
               for (j = 1; j &amp;lt; TokenLength; j++) &lt;br /&gt;
                   Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))]; &lt;br /&gt;
           } &lt;br /&gt;
           else { // Normal string. &lt;br /&gt;
               // Just add the characters normally. &lt;br /&gt;
               integer j; &lt;br /&gt;
               for (j = 0; j &amp;lt; TokenLength; j++) &lt;br /&gt;
                   Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))]; &lt;br /&gt;
           } &lt;br /&gt;
&lt;br /&gt;
           // Unset this flag, since this was not an escape sequence. &lt;br /&gt;
           LastWasEscapeSequence = FALSE; &lt;br /&gt;
       } &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   // Use the indices to create grid positions. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llList2Integer(Indices, 0) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llList2Integer(Indices, 1) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llList2Integer(Indices, 2) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llList2Integer(Indices, 3) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llList2Integer(Indices, 4) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) { &lt;br /&gt;
   // This converts from an ASCII based index to our indexing scheme. &lt;br /&gt;
   if (index &amp;gt;= 32) // &#039; &#039; or higher &lt;br /&gt;
       index -= 32; &lt;br /&gt;
   else { // index &amp;lt; 32 &lt;br /&gt;
       // Quick bounds check. &lt;br /&gt;
       if (index &amp;gt; 15) &lt;br /&gt;
           index = 15; &lt;br /&gt;
&lt;br /&gt;
       index += 94; // extended characters &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   return index; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default &lt;br /&gt;
{ &lt;br /&gt;
    state_entry() &lt;br /&gt;
    { &lt;br /&gt;
        // Initialize the character index. &lt;br /&gt;
        ResetCharIndex();&lt;br /&gt;
        llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);  &lt;br /&gt;
    } &lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer num)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer channel, string data, key id) &lt;br /&gt;
    { &lt;br /&gt;
    &lt;br /&gt;
        if (channel == SLAVE_RECOGNIZED)&lt;br /&gt;
        {&lt;br /&gt;
            if (data == llGetScriptName())&lt;br /&gt;
            {&lt;br /&gt;
                gActive=TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        if (channel == SLAVE_DISPLAY) &lt;br /&gt;
        { &lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
            &lt;br /&gt;
            &lt;br /&gt;
            RenderString(llList2Integer(params, 0),data);&lt;br /&gt;
            return; &lt;br /&gt;
        } &lt;br /&gt;
       &lt;br /&gt;
       if (channel == SLAVE_DISPLAY_EXTENDED) &lt;br /&gt;
       {&lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            RenderExtended(llList2Integer(params, 0),data);&lt;br /&gt;
       } &lt;br /&gt;
       &lt;br /&gt;
        if (channel == SET_FONT_TEXTURE) &lt;br /&gt;
        { &lt;br /&gt;
           gFontTexture = id; &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
       &lt;br /&gt;
        if (channel == REMAP_INDICES) { &lt;br /&gt;
           // Parse the message, splitting it up into index values. &lt;br /&gt;
           list Parsed = llCSV2List(data); &lt;br /&gt;
           integer i; &lt;br /&gt;
           // Go through the list and swap each pair of indices. &lt;br /&gt;
           for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) { &lt;br /&gt;
               integer Index1 = ConvertIndex( llList2Integer(Parsed, i) ); &lt;br /&gt;
               integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) ); &lt;br /&gt;
        &lt;br /&gt;
               // Swap these index values. &lt;br /&gt;
               string Value1 = llGetSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
               string Value2 = llGetSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
        &lt;br /&gt;
               gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
               gCharIndex = llInsertString(gCharIndex, Index1, Value2); &lt;br /&gt;
        &lt;br /&gt;
               gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
               gCharIndex = llInsertString(gCharIndex, Index2, Value1); &lt;br /&gt;
           } &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        if (channel == RESET_INDICES) { &lt;br /&gt;
           // Restore the character index back to default settings. &lt;br /&gt;
           ResetCharIndex(); &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        if (channel == SLAVE_RESET)&lt;br /&gt;
        {&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            gActive=FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
    } &lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Prim Setup (Caution!  Not compatible with 5 face double texture Xytext):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// XyzzyText Prim Setup Script (5 Face)&lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon&lt;br /&gt;
//&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        llSetPrimitiveParams([&lt;br /&gt;
                    PRIM_TYPE, PRIM_TYPE_PRISM, PRIM_HOLE_DEFAULT, &amp;lt;0.199, 0.8, 0.0&amp;gt;, 0.68, &amp;lt;0.0, 0.0, 0.0&amp;gt;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, &lt;br /&gt;
                    PRIM_SIZE, &amp;lt;0.03, 2.89, 0.5&amp;gt;, &lt;br /&gt;
                    PRIM_TEXTURE, 1, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.126, 0.10, 0.0&amp;gt;, &amp;lt;-0.740013, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 6, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.050, 0.100, 0.00&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 4, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;-0.740, 0.10, 0.00&amp;gt;, &amp;lt;0.130009, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 7, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.050, 0.100, 0.00&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 3, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.126, 0.10, 0.0&amp;gt;, &amp;lt;-0.255989, 0.0, 0.0&amp;gt;, 0.0]);&lt;br /&gt;
                    &lt;br /&gt;
        llRemoveInventory(llGetScriptName());&lt;br /&gt;
    } &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}{{LSLC|Examples}}&lt;/div&gt;</summary>
		<author><name>GP Runo</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Category:LSL_Controls&amp;diff=16819</id>
		<title>Category:LSL Controls</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Category:LSL_Controls&amp;diff=16819"/>
		<updated>2007-04-05T13:21:58Z</updated>

		<summary type="html">&lt;p&gt;GP Runo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
Controls in LSL generally refer to controlling {{LSLGC|Camera|cameras}} or {{LSLGC|Object|objects}}. {{LSLGC|Avatar}} input keys (movement keys and mouseclicks) can be caught and objects can be made to perform certain actions based on those keys, but you cannot &#039;&#039;control&#039;&#039; an agent&#039;s movement with LSL. &lt;br /&gt;
&lt;br /&gt;
However, you can control the camera of an agent as well as capture an agent&#039;s camera position and rotation. You can also determine if an agent is currently in mouselook.&lt;br /&gt;
&lt;br /&gt;
Before being able to do any of the above, the script must request the appropriate permissions from the agent with {{LSLG|llRequestPermissions}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately, there is no way to determine the position of the client&#039;s pointer using only LSL.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Usage Examples&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can force an Avatar into [[LlForceMouselook]] when they sit on an object to prepare them for interacting with that object.&lt;br /&gt;
&lt;br /&gt;
You can turn and move an object based on the Avatar&#039;s movement keys.&lt;br /&gt;
&lt;br /&gt;
You can check if an Avatar is looking at your object.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Functions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
: {{LSLG|llTakeControls}}&lt;br /&gt;
: {{LSLG|llSetCameraParams}}&lt;br /&gt;
: {{LSLG|llClearCameraParams}}&lt;br /&gt;
: {{LSLG|llReleaseControls}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Events&#039;&#039;&#039;&lt;br /&gt;
: {{LSLG|control}}&lt;/div&gt;</summary>
		<author><name>GP Runo</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Category:LSL_Controls&amp;diff=16818</id>
		<title>Category:LSL Controls</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Category:LSL_Controls&amp;diff=16818"/>
		<updated>2007-04-05T13:21:21Z</updated>

		<summary type="html">&lt;p&gt;GP Runo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
Controls in LSL generally refer to controlling {{LSLGC|Camera|cameras}} or {{LSLGC|Object|objects}}. {{LSLGC|Avatar}} input keys (movement keys and mouseclicks) can be caught and objects can be made to perform certain actions based on those keys, but you cannot &#039;&#039;control&#039;&#039; an agent&#039;s movement with LSL. &lt;br /&gt;
&lt;br /&gt;
However, you can control the camera of an agent as well as capture an agent&#039;s camera position and rotation. You can also determine if an agent is currently in mouselook.&lt;br /&gt;
&lt;br /&gt;
Before being able to do any of the above, the script must request the appropriate permissions from the agent with {{LSLG|llRequestPermissions}}&lt;br /&gt;
&lt;br /&gt;
Unfortunately, there is no way to determine the position of the client&#039;s pointer using only LSL.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Usage Examples&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can force an Avatar into LlForceMouselook when they sit on an object to prepare them for interacting with that object.&lt;br /&gt;
&lt;br /&gt;
You can turn and move an object based on the Avatar&#039;s movement keys.&lt;br /&gt;
&lt;br /&gt;
You can check if an Avatar is looking at your object.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Functions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
: {{LSLG|llTakeControls}}&lt;br /&gt;
: {{LSLG|llSetCameraParams}}&lt;br /&gt;
: {{LSLG|llClearCameraParams}}&lt;br /&gt;
: {{LSLG|llReleaseControls}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Events&#039;&#039;&#039;&lt;br /&gt;
: {{LSLG|control}}&lt;/div&gt;</summary>
		<author><name>GP Runo</name></author>
	</entry>
</feed>