Creative Commons License Machine/Kiosk Script

From Second Life Wiki
< Creative Commons License Machine
Revision as of 22:32, 22 September 2007 by Zarf Vantongerloo (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to 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.

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(); }
}