User:Kireji Haiku/A more complex freebie-giver (setup with notecard)

From Second Life Wiki
Jump to navigation Jump to search






This script has been provided by Kireji Haiku. It takes a while until you get a hang of the structure. This is my first more complex script. Parts of this script have been taken from this wiki, others of fullperm inworld scripts I have collected.

This setup here will give you:

  • A freebie giver, not a vendor.
  • A possibility for people to send an email to multiple recipients without them knowing the addresses. (Ok, you can change that, but I like it that way because I can use a private email-address nobody in SL needs to know about.)
  • A possibility to give a group or anybody multiple arrangements of freebies into folder, without a big hassle.
  • A very easy way to add stuff, once it has been setup. Although I have to say that the initial setup can be a bit nasty.




Setup-guide:

  • Create the final prim you want to use and put in the configuration-notecard. Make sure the name of that notecard ends with ".cfg". Then put the main script inside.
  • Put all stuff you want to give away into the same prim and set all scripts other than the configuration script to "not running".
  • Create a helper-prim for every button you want to use (as it is now, max is 9) and copy a list of the contents into it.
  • Setup your notecard with the help of the script for the helper-prim.
  • Recheck setup, remove spaces around "=" in the notecard between the command and the arguement.
  • DO NOT USE ITEMS YOU GIVE AWAY THAT CONTAIN A = IN THEIR NAME! AND BE ADVISED, THAT NAMES ARE CASE SENSITIVE. LONG SETUP NOTECARDS AND A LOT OF ITEMS CAN CRASH THIS SYSTEM EVENTUALLY, SO DON'T OVERDO IT, all'right?





You can do anything with this, but please be so kind and leave me a note if you use my work, thanks.

Script to put in desired prim(name doesn't matter here):

<lsl> list eMail_list = []; string default_floattext; string object_name; string object_description; string particle_texture; integer GROUPONLY; float timer_writeSubject; float timer_writeBody; float timer_mainmenu; float timer_emailer; float timer_remainButton; float timer_sendMail; key senderKey; string senderName; string subject; string bodyText; list writeButtons; string removeButton; integer i; integer TYPE_OF_TARGET = AGENT; float SCAN_DISTANCE = 25.0; integer STOP_INTERVAL = 20; string CONTROLLER_ID = "control_id";//IF YOU KNOW WHAT THIS IS AND WHAT IT DOES, CHANGE IT ;) integer AUTO_START = TRUE; list particle_parameters=[]; list target_parameters=[]; string scan_for_name; integer attempt_number; integer CHANNEL; string menu_text1 = "Welcome, "; string menu_text2 = ". If you want to send me an eMail click *EMAIL*, otherwise choose your object of desire below."; string option1; string option2; string option3; string option4; string option5; string option6; string option7; string option8; string option9; string info1; string info2; string info3; string info4; string info5; string info6; string info7; string info8; string info9; list list_option1; list list_option2; list list_option3; list list_option4; list list_option5; list list_option6; list list_option7; list list_option8; list list_option9; key name; integer ConfigRequired = TRUE; //DO NOT EVEN THINK ABOUT SETTING UP THE NOTECARD SUFFIX BY NOTECARD :P string ConfigNotecardSuffix = ".cfg";//IF YOU CHANGE THIS, MAKE SURE YOUR NOTECARD HAS THIS SUFFIX float ConfigTimeout = 60.0;//Yes, 60 seconds seems fine to me. integer ConfigLineIndex; key ConfigRequestID; list ConfigCards; string ConfigCardName; integer ConfigCardIndex; integer Debug;

config_init() {

   default_floattext = "now active";
   object_name = "menu driven giver by Kireji Haiku";//JUST BECAUSE, IT WILL CHANGE ANYWAY, RELAX :)
   particle_texture = "";
   CHANNEL = (integer)llFrand(DEBUG_CHANNEL)*-1;
   timer_writeSubject = 30.0;
   timer_writeBody = 120.0;
   timer_mainmenu = 30.0;
   timer_emailer = 30.0;
   timer_remainButton = 30.0;
   timer_sendMail = 30.0;
   list_option1 = [];
   list_option2 = [];
   list_option3 = [];
   list_option4 = [];
   list_option5 = [];
   list_option6 = [];
   list_option7 = [];
   list_option8 = [];
   list_option9 = [];
   eMail_list = [];
   option1 = "";
   option2 = "";
   option3 = "";
   option4 = "";
   option5 = "";
   option6 = "";
   option7 = "";
   option8 = "";
   option9 = "";
   info1 = "";
   info2 = "";
   info3 = "";
   info4 = "";
   info5 = "";
   info6 = "";
   info7 = "";
   info8 = "";
   info9 = "";
   //NO, I DID NOT FORGET THE DEBUG AND GROUPONLY
   //AND PLEASE DON'T PUT ANY init() VALUES HERE FOR THEM

}

config_dump() {

   say("eMail-Addresses: >> refer to setup notecard (this is a private list)");
       //IF YOU REALLY WANT THEM PUBLIC CHANGE THIS TO THE NEXT LINE AND WAY-DOWN FOR SENDING EMAIL AGAIN
       //THIS ONLY SHOWS FOR DEBUG==TRUE WHILE THE OTHER WAY
       //WAY-DOWN WILL SHOW IN ANY CASE IF YOU ENABLE IT
       //say("eMail-Addresses: " + llList2CSV(eMail_list));
   say("Floattext: " + default_floattext);
   say("My Name: " + object_name);
   say("My Channel for menu-communication is: " + (string) CHANNEL);
   say("Group-only access is: " + (string) GROUPONLY + "  (1.0 is on, 0.0 is off)");
   say("Texture for particles: " + particle_texture);
   say("Timer for Subject: " + (string) timer_writeSubject);
   say("Timer for Body: " + (string) timer_writeBody);
   say("Timer for main menu: " + (string) timer_mainmenu);
   say("Timer for eMail: " + (string) timer_emailer);
   say("Timer for Buttons: " + (string) timer_remainButton);
   say("Timer for sending eMail: " + (string) timer_sendMail);
   say("Button1: " + option1);
   say("Info1: " + info1);
   say("Button2: " + option2);
   say("Info2: " + info2);
   say("Button3: " + option3);
   say("Info3: " + info3);
   say("Button4: " + option4);
   say("Info4: " + info4);
   say("Button5: " + option5);
   say("Info5: " + info5);
   say("Button6: " + option6);
   say("Info6: " + info6);
   say("Button7: " + option7);
   say("Info7: " + info7);
   say("Button8: " + option8);
   say("Info8: " + info8);
   say("Button9: " + option9);
   say("Info9: " + info9);
   say("Contents1: " + llList2CSV(list_option1));
   say("Contents2: " + llList2CSV(list_option2));
   say("Contents3: " + llList2CSV(list_option3));
   say("Contents4: " + llList2CSV(list_option4));
   say("Contents5: " + llList2CSV(list_option5));
   say("Contents6: " + llList2CSV(list_option6));
   say("Contents7: " + llList2CSV(list_option7));
   say("Contents8: " + llList2CSV(list_option8));
   say("Contents9: " + llList2CSV(list_option9));
   say("Debug is currently on. Set debug to 0.0 in notecard if you don't like to see this config-note here.");

say("Current reset time was: " + llGetTimestamp()); }

config_parse(string str, string cardName, integer lineNum) {

   str = llStringTrim(str, STRING_TRIM_HEAD);
   if (llGetSubString(str,0,0) == "//") {
       return;
   }
   list ldata  = llParseStringKeepNulls(str, ["="], [""]);
   string cmd  = llList2String(ldata,0);
   string arg1 = llList2String(ldata,1);
   if (cmd == "@") {
       eMail_list += [arg1];
   } else if (cmd == "float") {
       default_floattext = arg1;
   } else if (cmd == "name") {
       object_name = arg1;
   }  else if (cmd == "texture") {
       particle_texture = arg1;
   } else if (cmd == "timer_writeSubject") {
       timer_writeSubject = (float) arg1;
   } else if (cmd == "timer_writeBody") {
       timer_writeBody = (float) arg1;
   } else if (cmd == "timer_mainmenu") {
       timer_mainmenu = (float) arg1;
   } else if (cmd == "timer_emailer") {
       timer_emailer = (float) arg1;
   } else if (cmd == "timer_remainButton") {
       timer_remainButton = (float) arg1;
   } else if (cmd == "timer_sendMail") {
       timer_sendMail = (float) arg1;
   } else if (cmd == "a") {
       option1 = arg1;
   } else if (cmd == "a_info") {
       info1 = arg1;
   } else if (cmd == "b") {
       option2 = arg1;
   } else if (cmd == "b_info") {
       info2 = arg1;
   } else if (cmd == "c") {
       option3 = arg1;
   } else if (cmd == "c_info") {
       info3 = arg1;
   } else if (cmd == "d") {
       option4 = arg1;
   } else if (cmd == "d_info") {
       info4 = arg1;
   } else if (cmd == "e") {
       option5 = arg1;
   } else if (cmd == "e_info") {
       info5 = arg1;
   } else if (cmd == "f") {
       option6 = arg1;
   } else if (cmd == "f_info") {
       info6 = arg1;
   } else if (cmd == "g") {
       option7 = arg1;
   } else if (cmd == "g_info") {
       info7 = arg1;
   } else if (cmd == "h") {
       option8 = arg1;
   } else if (cmd == "h_info") {
       info8 = arg1;
   } else if (cmd == "i") {
       option9 = arg1;
   } else if (cmd == "i_info") {
       info9 = arg1;
   } else if (cmd == "1") {
       list_option1 += [arg1];
   } else if (cmd == "2") {
       list_option2 += [arg1];
   } else if (cmd == "3") {
       list_option3 += [arg1];
   } else if (cmd == "4") {
       list_option4 += [arg1];
   } else if (cmd == "5") {
       list_option5 += [arg1];
   } else if (cmd == "6") {
       list_option6 += [arg1];
   } else if (cmd == "7") {
       list_option7 += [arg1];
   } else if (cmd == "8") {
       list_option8 += [arg1];
   } else if (cmd == "9") {
       list_option9 += [arg1];
   } else if (cmd == "debug") {
       Debug = (integer) arg1;
   } else if (cmd == "grouponly") {
       GROUPONLY = (integer) arg1;
   }

}

config_done() {

   if (Debug) {
       config_dump();
   }
   say("Configuration done.");

}

say(string str) {

   llSay(0, "Setup process: " + str);

}

integer next_card() {

   if (ConfigCardIndex >= llGetListLength(ConfigCards)) {
       ConfigCards = [];
       return (FALSE);
   }
   ConfigLineIndex = 0;
   ConfigCardName = llList2String(ConfigCards, ConfigCardIndex);
   ConfigCardIndex++;
   ConfigRequestID = llGetNotecardLine(ConfigCardName, ConfigLineIndex);
   say("Reading : " + ConfigCardName);
   return (TRUE);

}

writeSubject() {

   llListen(0, "", senderKey, "");
   llInstantMessage(senderKey, "Please say the subject of your email.");
   llSetTimerEvent(timer_writeSubject);

}

writeBody() {

   llListen(0, "", senderKey, "");
   llInstantMessage(senderKey, "Please say the message you would like to send.");
   llSetTimerEvent(timer_writeBody);

}

removeSubject() {

   i = llListFindList(writeButtons, ["Subject"]);
   writeButtons = llDeleteSubList(writeButtons, i, i);

}

removeMessage() {

   i = llListFindList(writeButtons, ["Message"]);
   writeButtons = llDeleteSubList(writeButtons, i, i);

}

default {

   state_entry() {
       llSetText("", <1.0,1.0,1.0>, 1.0);
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <0.5,0.5,0.5>, TRUE]);
       llSay(0, "default state...");
       state s_config;
   }
   state_exit() {
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,1.0,1.0>, TRUE]);
   }

}

state s_reconfig {

   state_entry() {
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <0.5,0.5,0.5>, TRUE]);
       llSay(0, "reconfiguring...");
       state s_config;
   }
   state_exit() {
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,1.0,1.0>, TRUE]);
   }

}

state s_config {

   state_entry() {
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,0.0,0.0>, TRUE]);
       llSetText("...busy...", <1.0,0.0,0.0>, 1.0);
       llSay(0, "configuring...");
       config_init();
       string item;
       ConfigCards = [];
       integer n = llGetInventoryNumber(INVENTORY_NOTECARD);
       while (n-- > 0) {
           item = llGetInventoryName(INVENTORY_NOTECARD, n);
           if (llSubStringIndex(item, ConfigNotecardSuffix) != -1) {
               ConfigCards += [item];
           }
       }
       ConfigCardIndex = 0;
       if (next_card()) {
           llSetTimerEvent(ConfigTimeout);
       } else if (ConfigRequired) {
           //OK, IF YOU REALLY HAD TO CHANGE THE SUFFIX, YOU MAY AS WELL CHANGE THIS ONE HERE
           say("Configuration notecard missing. Please make sure your notecard ends with .cfg");              
           state s_configRetry;
       } else {
           state s_active;
       }
   }

   dataserver(key query_id, string data) {
       if (query_id == ConfigRequestID) {
           if (data == EOF) {
               if (! next_card()) {
                   config_done();
                   state s_active;
               }
           } else {
               config_parse(data, ConfigCardName, ConfigLineIndex);
               ConfigRequestID = llGetNotecardLine(ConfigCardName, ++ConfigLineIndex);
               llSetTimerEvent(ConfigTimeout);
           }
       }
   }

   timer() {
       say("Dataserver time out: touch to retry");
       state s_configRetry;
   }

   on_rez(integer num) { state s_reconfig; }

   changed(integer change) {
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { state s_reconfig; }
   }

   state_exit() {
       llSetTimerEvent(0);
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,1.0,1.0>, TRUE]);
       llSay(0, "Ready for use!");
   }

}

state s_configRetry {

   state_entry() {
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,0.7,0.0>, TRUE]);
       llSetText("Setup failed, touch for retry.", <1.0,0.0,0.0>, 1.0);
       llSay(0, "Setup failed, touch for retry.");
   }
   touch_start(integer tot) {
       if (llDetectedKey(0) == llGetOwner()) {
           state s_config;
       }
   }

   changed(integer change) {
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { state s_config; }
   }
   state_exit() {
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,1.0,1.0>, TRUE]);
       llSetText("", <1.0,1.0,1.0>, 1.0);
   }

}

state s_unconfigured {

   state_entry() {
       llSetText("Configuration missing", <1.0,1.0,1.0>, 1.0);
       llSay(0, "Configuration missing.");
   }

   changed(integer change) {
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { state s_reconfig; }
   }

   state_exit() {
       llSetText("", <1.0,1.0,1.0>, 1.0);
   }

}

state s_active {

   state_entry()

{ object_description = "Last reset was: " + llGetTimestamp();

       llSetObjectDesc(object_description);
       llMessageLinked( LINK_SET, FALSE, CONTROLLER_ID, NULL_KEY );
       particle_parameters = [
           PSYS_SRC_TEXTURE, particle_texture,
           PSYS_PART_START_SCALE, <0.1, 0.1, FALSE>, PSYS_PART_END_SCALE, <0.1, 0.1, FALSE>,
           PSYS_PART_START_COLOR, <1.00,1.00,1.00>,    PSYS_PART_END_COLOR, <1.00,1.00,1.00>,
           PSYS_PART_START_ALPHA, (float) 1.0,         PSYS_PART_END_ALPHA, (float) 1.0,
           PSYS_SRC_BURST_PART_COUNT, (integer)  2,
           PSYS_SRC_BURST_RATE,         (float) 0.05,
           PSYS_PART_MAX_AGE,           (float)  10.0,
           PSYS_SRC_PATTERN, (integer) 2,
           PSYS_SRC_ACCEL, < 00.00, 00.00, -00.1>,
           PSYS_PART_FLAGS, (integer) ( 0
           | PSYS_PART_INTERP_COLOR_MASK
           | PSYS_PART_INTERP_SCALE_MASK
           | PSYS_PART_EMISSIVE_MASK
           | PSYS_PART_FOLLOW_VELOCITY_MASK
           | PSYS_PART_WIND_MASK
           | PSYS_PART_TARGET_POS_MASK
           )
               ];
       if ( AUTO_START )
       {
           llParticleSystem( particle_parameters );
       }
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,1.0,1.0>, TRUE]);
       //I would kindly ask you NOT to change the following line
       llSetText(default_floattext + "\n*system provided by Kireji Haiku*", <1.0,1.0,1.0>, 1.0);
       llSetObjectName(object_name);
       writeButtons = ["Subject", "Message"];
       senderKey = llDetectedKey(0);
       llListen(CHANNEL, "", senderKey, "");
   }
   touch_start(integer num)
   {
   integer i=0;
   senderKey = llDetectedKey(i);
   senderName = llKey2Name(llDetectedKey(i));
   if (GROUPONLY) {
       while(i<num)
       {
           key id=llDetectedKey(i);
           if(llSameGroup(id))
           {
               llSay(0, "Please choose from menu.");
               llDialog(senderKey, menu_text1 + senderName + menu_text2, [ option7,option8,option9, option4, option5, option6, option1, option2, option3,"EMAIL" ], CHANNEL );
               llInstantMessage(llGetOwner(), "/me was touched by: " + senderName);
           }
           else
           {

llSay(0, "This only works if you have the right group-tag activated."); llSay(0, "Please try again after changing your group-tag to match my active group."); llSay(0, "You can right-click, edit me and check the general tab to be sure you activated the right one.");

           }
           ++i;
       }
   }
   else {
       llSay(0, "Please choose from menu.");
       llDialog(senderKey, menu_text1 + senderName + menu_text2, [ option7,option8,option9, option4, option5, option6, option1, option2, option3,"EMAIL" ], CHANNEL );
       llInstantMessage(llGetOwner(), "/me was touched by: " + senderName);
   }
   scan_for_name = llKey2Name(llDetectedKey(i));
   attempt_number=1;
   llStringTrim( scan_for_name, STRING_TRIM );
   llSensor( scan_for_name, "", TYPE_OF_TARGET,  SCAN_DISTANCE, TWO_PI );
   llSetTimerEvent(timer_mainmenu);
   }
   listen(integer channel, string name, key id, string message)
   {
       if(message == "EMAIL")
       {

llSay(0, "Currently being used by " + senderName + "."); llSay(0, "Changing state to email_setup ...");

           state emailer;
       }
       if (message == option1)
       {
           llGiveInventoryList(id, option1, list_option1);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option1); llSay(0, "EXTRA INFO: " + info1);

       }
       if (message == option2)
       {
           llGiveInventoryList(id, option2, list_option2);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option2); llSay(0, "EXTRA INFO: " + info2);

       }
       if (message == option3)
       {
           llGiveInventoryList(id, option3, list_option3);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option3); llSay(0, "EXTRA INFO: " + info3);

       }
       if (message == option4)
       {
           llGiveInventoryList(id, option4, list_option4);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option4); llSay(0, "EXTRA INFO: " + info4);

       }
       if (message == option5)
       {
           llGiveInventoryList(id, option5, list_option5);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option5); llSay(0, "EXTRA INFO: " + info5);

       }
       if (message == option6)
       {
           llGiveInventoryList(id, option6, list_option6);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option6); llSay(0, "EXTRA INFO: " + info6);

       }
       if (message == option7)
       {
           llGiveInventoryList(id, option7, list_option7);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option7); llSay(0, "EXTRA INFO: " + info7);

       }
       if (message == option8)
       {
           llGiveInventoryList(id, option8, list_option8);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option8); llSay(0, "EXTRA INFO: " + info8);

       }
       if (message == option9)
       {
           llGiveInventoryList(id, option9, list_option9);

llSay(0, "Please look in your inventory under recent items to find your new stuff. It should be in a folder named: " + option9); llSay(0, "EXTRA INFO: " + info9);

       }
   }
   timer()
   {
       llSetTimerEvent(0);
       llSay(0, "You, " + senderName + ", have failed to select an option in time. Unit is resetting and then available for retry.");

llSay(0, "Please wait..."); llSetText("",<0,0,0>, 0);

       llMessageLinked( LINK_SET, FALSE, CONTROLLER_ID, NULL_KEY );
       llResetScript();
   }
   on_rez(integer start_param)
   {
       llResetScript();
   }
   sensor(integer number_of_matches)
   {
       if ( attempt_number == 1 )
       {
           llMessageLinked( LINK_SET, 2, CONTROLLER_ID, llDetectedKey(0) );
           llSetTimerEvent( STOP_INTERVAL );
       }
       else
       {
           integer i;
           scan_for_name = llToLower(scan_for_name);
           for ( i=0; i<number_of_matches; i++)
           {
               if ( llSubStringIndex(llToLower(llDetectedName(i)), scan_for_name) >= 0 )
               {
                   llMessageLinked( LINK_SET, 2, CONTROLLER_ID, llDetectedKey(i) );
                   llSetTimerEvent( STOP_INTERVAL );
                   return;
               }
           }
           llOwnerSay("error: I can't find \""+scan_for_name+"\" within "+(string)SCAN_DISTANCE+"m.");
           llResetScript();
       }
   }
   no_sensor()
   {
       if ( attempt_number == 1 )
       {
           llSensor( "", "", TYPE_OF_TARGET,  SCAN_DISTANCE, TWO_PI );
           attempt_number = 2;
       }
       else
       {
           llMessageLinked( LINK_SET, FALSE, CONTROLLER_ID, NULL_KEY );
           llOwnerSay("error: I can't find anyone named "+scan_for_name+" within "+(string)SCAN_DISTANCE+"m.");
           llResetScript();
       }
   }
   link_message( integer sibling, integer num, string mesg, key target_key )
   {
       if ( mesg != CONTROLLER_ID )
       {
           return;
       }
       else if ( num == 0 )
       {
           llParticleSystem( [ ] );
       }
       else if ( num == 1 )
       {
           llParticleSystem( particle_parameters + target_parameters );
       }
       else if ( num == 2 )
       {
           target_parameters = [ PSYS_SRC_TARGET_KEY, target_key ];
           llParticleSystem( particle_parameters + target_parameters );
       }
       else
       {
           //do nothing
       }
   }
   changed(integer change)
   {
       if (change & CHANGED_LINK)
       {
           integer link = llGetNumberOfPrims();
           key id;
           while(llGetAgentSize(id = llGetLinkKey(link--)))
               {
               llUnSit(id); llSay(0, "Does this look like a chair?");
               }
       }
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { llResetScript(); }
   }

}

state emailer {

   state_entry()
   {
       llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <0.0,1.0,0.0>, TRUE]);
       if(writeButtons == [])
       {
           state sendMail;
       }
       llListen(CHANNEL, "", llDetectedKey(0), "");
       llSetTimerEvent(timer_emailer);
       llInstantMessage(senderKey, "You have 30 seconds to choose.");
       llSetText("Currently in use by " + (string)llKey2Name(senderKey) + ". Please wait!", <1.0,0.0,0.0>, 1.0);
       llDialog(senderKey, "What part of your message would you like to write?", writeButtons, CHANNEL);
   }
   listen(integer channgel, string name, key id, string message)
   {
       if(message == "Subject")
       {
           state subjectWrite;
       }
       else if(message == "Message")
       {
           state messageWrite;
       }
   }
   timer()
   {
       llSetTimerEvent(0);
       llSay(0, "You, " + senderName + ", have failed to select an option in time. Unit is resetting and then available for retry.");

llSay(0, "Please wait...");

       llSetText("",<0,0,0>, 0);
       state default;
   }
   on_rez(integer start_param)
   {
       llResetScript();
   }
   changed(integer change) {
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { llResetScript(); }
   }

}

state subjectWrite {

   state_entry()
   {

llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,0.0,0.0>, TRUE]); llSetText("Currently in use by " + (string)llKey2Name(senderKey) + ". Please wait!", <1.0,0.0,0.0>, 1.0);

       writeSubject();
   }
   listen(integer channel, string name, key id, string message)
   {
       subject = message;
       removeButton = "Subject";
       state remainButton;
   }
   timer()
   {
       llSetTimerEvent(0);
       llSay(0, "You, " + senderName + ", have failed to select an option in time. Unit is resetting and then available for retry.");

llSay(0, "Please wait...");

       state emailer;
   }
   on_rez(integer start_param)
   {
       llResetScript();
   }
   changed(integer change) {
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { llResetScript(); }
   }

}

state messageWrite {

   state_entry()
   {

llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,0.0,0.0>, TRUE]); llSetText("Currently in use by " + (string)llKey2Name(senderKey) + ". Please wait!", <1.0,0.0,0.0>, 1.0);

       writeBody();
   }
   listen(integer channel, string name, key id, string message)
   {
       bodyText = message;
       removeButton = "Message";
       state remainButton;
   }
   timer()
   {
       llSetTimerEvent(0);
       llSay(0, "You, " + senderName + ", have failed to select an option in time. Unit is resetting and then available for retry.");

llSay(0, "Please wait...");

       state emailer;
   }
   on_rez(integer start_param)
   {
       llResetScript();
   }
   changed(integer change) {
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { llResetScript(); }
   }

}

state remainButton {

   state_entry()
   {

llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <0.0,0.0,0.0>, TRUE]); llSetText("Currently in use by " + (string)llKey2Name(senderKey) + ". Please wait!", <1.0,0.0,0.0>, 1.0);

       llSetTimerEvent(timer_remainButton);
       if(removeButton == "Subject")
       {
           removeSubject();
           state emailer;
       }
       else if(removeButton == "Message")
       {
           removeMessage();
           state emailer;
       }
   }
   timer()
   {
       llSetTimerEvent(0);
       llSay(0, "You, " + senderName + ", have failed to select an option in time. Unit is resetting and then available for retry.");

llSay(0, "Please wait...");

       state emailer;
   }
   on_rez(integer start_param)
   {
       llResetScript();
   }
   changed(integer change) {
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { llResetScript(); }
   }

}

state sendMail {

   state_entry()
   {

llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <1.0,1.0,0.0>, TRUE]); llSetText("Currently in use by " + (string)llKey2Name(senderKey) + ". Please wait!", <1.0,0.0,0.0>, 1.0);

       llSetTimerEvent(timer_sendMail);
       llListen(CHANNEL, "", senderKey, "Yes");
       llListen(CHANNEL, "", senderKey, "No");
       llInstantMessage(senderKey, "Your email reads as the followed:");
       //llSay(0, "EMAIL-ADDRESSES: " + llList2CSV(eMail_list));//SHOW IF YOU LIKE TO GIVE YOUR MAILADDRESS OR HIDE OTHERWISE
       llInstantMessage(senderKey, "SUBJECT:      " + subject);
       llInstantMessage(senderKey, "EMAIL-TEXT:  " + bodyText);
       llDialog(senderKey, "Do you wish to send this message?", ["Yes","No"], CHANNEL);
   }
   listen(integer channel, string name, key id, string message)
   {
       if(message == "Yes")
       {
           llInstantMessage(senderKey, "I hope you don't mind " + senderName + ", but I will have to assume your name for a moment to send this email.");
           llInstantMessage(senderKey, "Your email will be sent in 20 seconds.");
           llInstantMessage(senderKey, "Thank you " + senderName + ", for using the " + llGetObjectName());
           llSetText("", <0,0,0>, 0);
           llSetObjectName(senderName);
           integer recipient;
           for (recipient = 0; recipient < llGetListLength(eMail_list); recipient++)
               {
                   llEmail(llList2String(eMail_list,recipient), subject, bodyText);
               }
           llInstantMessage(senderKey, "Email has been sent. I'm ready for the next try.");
           state default;
       }
       else if(message == "No")
       {
           llInstantMessage(senderKey, "Thank you " + senderName + ", for using " + llGetObjectName());
           llSetText("", <0,0,0>, 0);
           llInstantMessage(senderKey, "I'm ready for the next try.");
           state default;
       }
   }
   timer()
   {
       llSetTimerEvent(0);
       llSay(0, "You, " + senderName + ", have failed to select an option in time. Unit is resetting and then available for retry.");

llSay(0, "Please wait...");

       state default;
   }
   on_rez(integer start_param)
   {
       llResetScript();
   }
   changed(integer change) {
       if (change & CHANGED_OWNER) { llResetScript(); }
       if (change & CHANGED_INVENTORY) { llResetScript(); }
   }

} </lsl>


You can do anything with this, but please be so kind and leave me a note if you use my work, thanks.


Notecard to put in desired prim:

  • Keep timer for sending mail above 30 seconds.
  • Use script after this notecard to create lists.
  • Any name followed by .cfg is fine.

<lsl> //no space before and after "="!!! //comment lines start with two forward slashes //debug is 1.0 or 0.0 //grouponly is 1.0 or 0.0 // @=test_address1@mail.com @=test_address2@mail.com @=test_address3@mail.com float=Notecards for lessons name=Notecard terminal texture=cda52928-37a5-c7cd-23bc-a8e6330ef28c timer_writeSubject=30 timer_writeBody=120 timer_mainmenu=30 timer_emailer=30 timer_remainButton=30 timer_sendMail=45 debug=0.0 grouponly=1.0 // //comments: //a through i are the button names. //1 through 9 are the list names for buttons a through i. //one line per list item! // a=button 1 name a_info=info 1 text b=button 2 name b_info=info 2 text c=button 3 name c_info=info 3 text d=button 4 name d_info=info 4 text e=button 5 name e_info=info 5 text f=button 6 name f_info=info 6 text g=button 7 name g_info=info 7 text h=button 8 name h_info=info 8 text i=button 9 name i_info=info 9 text // 1=1a 1=1b 1=1c 1=1d 1=1e 1=1f 2=2a 2=2b 2=2c 2=2d 2=2e 2=2f 3=3 4=4a 4=4b 5=5 6=6 //7-9 give nothing, returns error and then resets //remove slashes to enable //7= //8= //9= // </lsl>


You can do anything with this, but please be so kind and leave me a note if you use my work, thanks.


Use this script for creating a list:

  • Make a copy of the content list for every button in different prims.
  • Name the object with the list name for your desired button, not the button name.
  • Example for above, your button "a" gives you a list of the items listed under "1". Name your prim "1"
  • You can copy&paste the created local chat text into the notecard and replace your "timestamp + prim_name:" with "prim_name=" for every line
  • Yeah, sorry. That's the fastest way for the first setup, adding single items later is a lot faster.

<lsl> integer len; integer i; integer typ;

default {

   state_entry()
   {
   llSay(0,"touch me to get your list");
   //do nothing 
   }
   touch_start(integer total_number)
   {
       string name = llGetObjectName();
       typ = INVENTORY_ALL;
       len =  llGetInventoryNumber(typ);
       for(i=0;i<=len-1;i++)
       {
           llSay(0, llGetInventoryName(typ,i));
       }
   }

} </lsl>