Creative Commons License Machine/Kiosk Script

From Second Life Wiki
Jump to: navigation, search

The kiosk is actually just a general purpose state machine engine. The particular state machine that is used for the Creative Commons LIcense Machine is in the Creative Commons License Machine/Kiosk Program.

<lsl> key gBlankTexture = "5748decc-f629-461c-9a36-a35a221fe21f"; // well known

float gTimeOut = 60.0;

integer gUserListener = 0;

integer gLicenseChannel = 0; integer gLicenseListener = 0;

string gNode; list gPath;

   // path of nodes, including current node at the end

key gUser = NULL_KEY;

   // user we are interacting with
   

list gParams;

   // user parameters, stride two: [ <key>, <value> ... ]

string gAltTrigger; key gArgID; string gArgMessage;


clearUse() {

   gNode = "";
   gPath = [ ];
   gUser = NULL_KEY;
   gParams = [ ];
   
   clearNode();

}

clearNode() {

   gTimeOut = 30.0;

}

cmdGo(string node) {

   gNode = node;
   gPath += [ node ];
   llMessageLinked(LINK_THIS, 200, node, NULL_KEY);
   
   clearNode();
   runAnyAction("init", "", NULL_KEY, "");
   
   llSetTimerEvent(gTimeOut);
   if (gUserListener) { llListenRemove(gUserListener); }
   gUserListener = llListen(0, "", gUser, "");

}

cmdReset() {

   clearUse();
   cmdGo("start");

}

cmdBack() {

   integer n = llGetListLength(gPath);
   if (n >= 2) {
       string node = llList2String(gPath, -2);
       gPath = llDeleteSubList(gPath, -2, -1);
       cmdGo(node);
   }
   else {
       cmdReset();
   }

}


cmdUser(key id) {

   gUser = id;

}

cmdAnyone() {

   gUser = NULL_KEY;

}

cmdTimeOut(float t) {

   gTimeOut = t;

}

cmdImage(string inv) {

   llSetTexture(inv, 0);

}

cmdSay(string text) {

   llSay(0, text);

}

cmdMovie() { }

cmdGive(string inv) {

   llGiveInventory(gUser, inv);

}

cmdWebsite() {

   llLoadURL(gUser, "View the Creative Commons web site.",
       "http://creativecommons.org/");

}


cmdSet(string param, string value) {

   integer i = llListFindList(gParams, [ param ]);
   if (i < 0) {
       gParams += [ param, value ];
   }
   else {
       gParams = llListReplaceList(gParams, [ value ], i + 1, i + 1);
   }

}

cmdSetUser(string param) {

   cmdSet(param, llKey2Name(gUser));

}

cmdSetNow(string param) {

   cmdSet(param, llGetSubString(llGetDate(), 0, 3));

}

string getParam(string param) {

   integer i = llListFindList(gParams, [ param ]);
   if (i < 0) return "";
   
   return llList2String(gParams, i + 1);

}

cmdReport(string param, string prompt) {

   string value = getParam(param);
   if (value == "") return;
   
   llSay(0, prompt + value);

}

cmdLicenseImage() {

   string commercialUse = getParam("commercial-use");
   string modifications = getParam("modifications");
   
   string license = "by";
   if (commercialUse == "no")      { license += "-nc"; }
   if (modifications == "no")      { license += "-nd"; }
   if (modifications == "share")   { license += "-sa"; }
   
   string imageName = "lic-" + license;
   cmdImage(imageName);
   
   cmdSet("image-key", llGetInventoryKey(imageName));

}

cmdLicenseRez() {

   gLicenseChannel = 10000000 + (integer)llFrand(10000000.0);
   gLicenseListener = llListen(gLicenseChannel, "", NULL_KEY, "");
   
   rotation r = llEuler2Rot(<0, -45, 0> * DEG_TO_RAD) * llGetRot();
   
   llRezObject("badge",
       llGetPos() + <-0.358, 0.0, 0.523> * r,
       ZERO_VECTOR,
       r,
       gLicenseChannel);

}

finishLicense() {

   llListenRemove(gLicenseListener);
   
   integer n = llGetListLength(gParams);
   integer i;
   for (i = 0; i < n; i += 2) {
       string param = llList2String(gParams, i);
       string value = llList2String(gParams, i + 1);
       llSay(gLicenseChannel, param + ":" + value);
   }
   
   rotation r = llEuler2Rot(<0, -45, 0> * DEG_TO_RAD) * llGetRot();
   vector p = llGetPos() + <-0.358, 0.0, 0.761> * r;
   llSay(gLicenseChannel, "done " + (string)p);

}

cmdLicenseDie() {

   if (gLicenseChannel != 0) {
       llSay(gLicenseChannel, "die");
       gLicenseChannel = 0;
   }

}


executeStatement(string statement) {

   integer sep = llSubStringIndex(statement, "|");
   string tail = "";
   if (sep >= 1) {
       tail = llGetSubString(statement, sep + 1, -1);
       statement = llGetSubString(statement, 0, sep - 1);
   }
   list parts = llParseString2List(statement, [ " " ], [ ]);
   if (tail != "") {
       parts += [ tail ];
   }
   
   string cmd = llList2String(parts, 0);
   string arg1 = llList2String(parts, 1);
   string arg2 = llList2String(parts, 2);
   if (arg2 == "*") { arg2 = gArgMessage; }
       
        if (cmd == "back")     { cmdBack(); }
   else if (cmd == "go")       { cmdGo(arg1); }
   else if (cmd == "reset")    { cmdReset(); }
   else if (cmd == "user")     { cmdUser(gArgID); }
   else if (cmd == "anyone")   { cmdAnyone(); }
   else if (cmd == "timeout")  { cmdTimeOut((float)arg1); }
   else if (cmd == "image")    { cmdImage(arg1); }
   else if (cmd == "say")      { cmdSay(arg1); }
   else if (cmd == "movie")    { cmdMovie(); }
   else if (cmd == "give")     { cmdGive(arg1); }
   else if (cmd == "website")  { cmdWebsite(); }
   else if (cmd == "set")      { cmdSet(arg1, arg2); }
   else if (cmd == "setUser")  { cmdSetUser(arg1); }
   else if (cmd == "setNow")   { cmdSetNow(arg1); }
   else if (cmd == "report")   { cmdReport(arg1, arg2); }
   else if (cmd == "licenseImage") { cmdLicenseImage(); }
   else if (cmd == "licenseRez")   { cmdLicenseRez(); }
   else if (cmd == "licenseDie")   { cmdLicenseDie(); }
   else {
       llOwnerSay("Unknown command: " + cmd);
   }

}

executeBlock(string block) {

   list statements = llParseString2List(block,
       [ " ; ", " ;", "; ", ";" ], [ ]);
   integer n = llGetListLength(statements);
   integer i;
   for (i = 0; i < n; ++i) {
       executeStatement(llList2String(statements, i));
   }

}

runAnyAction(string trigger, string altTrigger, key id, string message) {

   gAltTrigger = altTrigger;
   gArgID = id;
   gArgMessage = message;
   
   llMessageLinked(LINK_THIS, 300, trigger, NULL_KEY);

}


default {

   state_entry() {
       llSetTexture(gBlankTexture, 0);
       llOwnerSay("Touch to start up.");
   }
   
   touch_start(integer n)
   {
       if (llDetectedKey(0) == llGetOwner()) {
           state readProgram;
       }
       else {
           llSay(0, "This kiosk is under construction.");
       }
   }

}

state readProgram {

   state_entry() {
       llSetTexture(gBlankTexture, 0);
       llMessageLinked(LINK_THIS, 100, "", NULL_KEY);
   }
   
   state_exit() {
       llOwnerSay("main memory: " + (string)llGetFreeMemory());
   }
   link_message(integer sender, integer num, string str, key id) {
       if (num == 101) {
           state run;
       }
   }
   touch_start(integer n) { }
   on_rez(integer n) { llResetScript(); }

}

state run {

   state_entry() {
       cmdReset();
   }
   
   state_exit() {
       llSetTimerEvent(0.0);
   }
       
   touch_start(integer n) {
       key id = llDetectedKey(0);
       if (gUser != NULL_KEY  &&  gUser != id) { return; }
       runAnyAction("touch", "", id, "");
       llSetTimerEvent(gTimeOut);
   }
   
   listen(integer ch, string who, key id, string message) {
       if (ch != 0  &&  ch == gLicenseChannel) {
           finishLicense();
           return;
       }
       
       string trigger = "\"" + llToLower(message) + "\"";
       runAnyAction(trigger, "listen", id, message);
       llSetTimerEvent(gTimeOut);
   }
   changed(integer what) {
       if (what & CHANGED_INVENTORY) {
           state readProgram;
       }
   }
   
   link_message(integer sender, integer num, string str, key id) {
       if (num == 301) {
           executeBlock(str);
       }
       else if (num == 399) {
           if (gAltTrigger != "") {
               llMessageLinked(LINK_THIS, 300, gAltTrigger, NULL_KEY);
               gAltTrigger = "";
           }
       }
   }
   timer() {
       cmdReset();
   }
   
   on_rez(integer n) { llResetScript(); }

} </lsl>