User:Luisa Bourgoin/Burn2

From Second Life Wiki
Jump to navigation Jump to search

The Burning Man Temple rebuilt inside SecondLife

If you take a tour around Flickr, searching for snapshots of the original built you will see visitors left inscriptions on the construction wood. I aimed for establishing something similar for the SL Temple rebuilt.

The technology restrictions are very limiting. Since some years the most one can do to add text onto a Prim is using hoovertext. The LSL call llSetText() allows showing up to somewhat 255 chars above a Prim.

Some tinkering revealed that the position of the text shown is dependant on the Z size of the Primitive. Mostly one experiences hoovertext floating way above of any item, because builders can't change Z size to make it fit better, in any cases.

Taking these two ideas, using small Z sizes and a substring of the total data amount of user-recorded text has lead onto the following code. It scrolls through the user recorded chat messages. People left up to a dozen poem lines on the construction plywood that years.

<lsl>// Created early in September 2012 by Luisa Bourgoin for the Burn2 Temple built // published under Creative Commons on the Second Life wiki 9/23/2012

//use a cube like 2.00 2.00 0.05 size. the Z size decideds how high above a prim the hoovertext //appears, so using flat small Z values make it visible almost on center of a prim, turned by 90° //you can slice it a bit for better fitting

string boilerplate = "(click & chat to inscript)\n"; integer max_message_lines = 50; //memory limitation integer visible_lines = 4; //only some 255 chars can be shown, so short lines can be shown more visibly vector color = <255, 255, 255>; float wipe_hours = -1; //if you want a scratchboard that cleans every N hours integer owner_only = FALSE;


//no serviceable parts below this line integer open = TRUE; integer LISTEN_HANDLE_1 = -1; list marque_text = []; string text = "\n\n\n\n"; //consider visible_lines integer marque_line = 0;

string left(string src, string divider) {

   integer index = llSubStringIndex(src, divider);
   if(~index)
       return llDeleteSubString(src, index, -1);
   return src;

}

string DisplayName(key ID) {

   string name = llGetDisplayName(ID);
   if(name == "???") name = llList2String(llGetObjectDetails(ID, [OBJECT_NAME]), 0); //gaaaah.. Displaynames!
   return name;

}

default {

   state_entry()
   {
       llResetTime();
       llSetTimerEvent(3.17); //scrolling speed reasonably low!
       marque_line = 0;
       color = color / 255.0;
   }
   touch_start(integer num_detected)
   {
       if(open && llGetListLength(marque_text) <= max_message_lines)
       {
           key ID = llDetectedKey(0);
           if(owner_only && ID != llGetOwner()) return;
           string displayname = left(DisplayName(ID), " ");
           llListenRemove(LISTEN_HANDLE_1);
           LISTEN_HANDLE_1 = llListen(0, "", ID, "");
           llSay(0, "Welcome to the Temple, "+displayname+". To leave an inscript please chat a single textline in between next 20 seconds!\n(You can use \\n for line breaks)");
       }
   }
   
   listen(integer listenchannel, string name, key id, string message)
   {
       llListenRemove(LISTEN_HANDLE_1);
       
       if(id == llGetOwner())
       {
           if(message == "dump")
           {
               integer i=0;
               for(; i<llGetListLength(marque_text); i++) {
                   llSay(0, llList2String(marque_text, i));
                   llSleep(0.2); //otherwise, chatlines order can get garbled!
               }
               return;
           }
           if(message == "open") {
               open = TRUE;
               return;
           }
           if(message == "closed") {
               open = FALSE;
               LISTEN_HANDLE_1 = llListen(0, "", llGetOwner(), "open"); //sic!
               return;
           }
           if(llGetSubString(message,0,5) == "delete") {
               string pattern = llGetSubString(message,7,-1);
               integer i=0;
               for(; i<llGetListLength(marque_text); i++)
               {
                   if(llSubStringIndex(llList2String(marque_text, i), pattern) >= 0)
                   {
                       marque_text = llDeleteSubList(marque_text, i, i);
                       i--; //since it just shortened
                   }
               }
               text = llDumpList2String(marque_text, "\n");
               return;
           }
       }
       
       if(owner_only && id != llGetOwner()) return;
           
       message = llDumpList2String(llParseStringKeepNulls((message = "") + message, ["\\n"], []), "\n");
       text = text + message + "\n\n";
       marque_text = llParseStringKeepNulls(text+"\n\n\n\n\n", ["\n"], []);
   }
   
   timer()
   {
       //timeouts are missing :(

//~ if(LISTEN_HANDLE_1 != -1 && ) //~ { //~ llListenRemove(LISTEN_HANDLE_1); //~ LISTEN_HANDLE_1 = -1; //~ }

       if(wipe_hours > 0 && (llGetTime() / 3600.0) > wipe_hours) llResetScript();
           
       //handles the scrolling effect called 'marque' herein
       if((marque_line + visible_lines) >= llGetListLength(marque_text)) marque_line = 0;
       if(open && llGetListLength(marque_text) <= max_message_lines)
           llSetText(boilerplate+llDumpList2String(llList2List(marque_text,marque_line,marque_line+visible_lines), " \n")+" \n", <1,1,1>,1);
       else
           llSetText(llDumpList2String(llList2List(marque_text,marque_line,marque_line+visible_lines), " \n")+" \n", <1,1,1>,1);
       marque_line++;
   }

}

//~ eof</lsl>