Bartender

From Second Life Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Bartender! v1.0.0

Bartender to serve drinks.. and other things.
Drop this script in your bartender prim.
Drop a bunch of 'drink' objects into your bartender prim.
Touch the bartender prim and select a drink.
Some debugging info is transmitted on llOwnerSay, but spam is minimal. Edit the script variable to adjust this.
This script differs from others in that:
It opens a single random negative channel, it does not activate an llListen *every time* someone clicks it.
IF the random channel is being used by something else, and this causes the bartender to get a bunch of garbage inputs, it will automatically change to a new random channel, and optionally inform the owner.
Evidently this script can be used as a kind of object freebie vendor too.
NOTES:
It's been a while since I wrote it, and it was never really extensively tested, so i expect there is some stupid in it. But AFAIK it's fine.
It features a primitive kind of double-touch prevention that i don't use anymore, so I guess the touch functions have been improved.. yeah.. that was it.. i think.. yeah. So there are some redundant bits.

//
// BETLOG Hax
// for Aley Arai AEST: 20080328 0645 [SLT:  20080327 1345]
// Written to allow easier use - just dump drink objects into inv and you are done.
// No more editing script drink lists.
//=========================================================================
// ---LICENCE START---
// http://creativecommons.org/licenses/by-sa/3.0/
// ie: Attribution licence:
//   Give me credit by leaving it in the script I created.
//   Supply my original script with your modified version.
//   Refer to the wiki URL from which you copied this script.
//      https://wiki.secondlife.com/wiki/Bartender
// ---LICENCE END---
//=========================================================================

//----------------------------------
// SHARED CONFIGURATION
//----------------------------------
// CONFIGURATION
//
//OPTIONAL debug feedback - 0=off, 1=Channel & Noise info, 2=all debug
integer gDebug              = 
                                //0;
                                1;
                                //2;
//
//number of invalid messages received before re-randomizing channel
integer gChannelNoiseMax    = 5; 
//
// message that appears on the dialog
string  gDlgMessage         = "\n\t\n\t\n\t\t\tMay I offer you a drink?";
//
// Optional chat responses
// leave BOTH of these fields blank ( ""; ) to NOT speak a message
// leave one OR the other blank to alter the form of the message
//recipient name is auto-inserted between these two
string  gMsgResponseA       = "Thanks";
// target name ends up here
string  gMsgResponseB       = ", enjoy your drink. :)";
//----------------------------------
// CORE CODE
integer gListenHandle       = 0;
integer gDlgLimiter         = 0;
integer gDlgChannel         = -5746547; //failsafe only
list    gDrinksList         = [];
integer gDrinksCount        = 0;
integer gChannelNoise       = 0;
//----------------------------------
f_dialogMenu(key id, list dlgButtons)
{   llDialog(id, gDlgMessage, dlgButtons, gDlgChannel);
    if (gDebug > 1)
    {   llOwnerSay("***OFFERING DIALOG:***"
            +"\nname: "+llKey2Name(id)
            +"\nid: "+(string)id
            +"\ngDlgMessage: "+gDlgMessage
            +"\ndlgButtons: "+llList2CSV(dlgButtons)
            +"\ngDlgChannel: "+(string)gDlgChannel
            +"\n***************"
        );
    }
}
//-----------------------
f_dialogNullify()
{   gDlgLimiter = 0;    
}
//-----------------------
f_randomChannel()
{   
//a static channel is more reliable where many people may request a drink while another is still considering the choices
//gChannelNoise will trigger auto-re-randomization of this static channel if too much invalid message activity is detected
    if (gListenHandle)
        llListenRemove(gListenHandle);
    gDlgChannel = (integer)(llFrand(-0x7FFFFFFF)-1);
    gListenHandle = llListen(gDlgChannel, "", "", ""); 
    if (gDebug)
        llOwnerSay("gDlgChannel: "+(string)gDlgChannel);
}
//-----------------------
f_assessInventory()
{   integer    i;
    integer    n = llGetInventoryNumber(INVENTORY_OBJECT);
    gDrinksList = [];
    for(i=0; i<n; i++ )
        gDrinksList += [ llGetInventoryName(INVENTORY_OBJECT, i) ];
    gDrinksCount = llGetListLength(gDrinksList);
    if (gDebug > 1)
        llOwnerSay("gDrinksCount: "+(string)gDrinksCount+" - gDrinksList: "+llList2CSV(gDrinksList));        
}
//-----------------------
default
{   on_rez(integer start_param)
    {   llResetScript();
    }
    changed(integer change)
    {   if (change & CHANGED_INVENTORY)
        {   llSetText("RE-EVALUATING\ninventory.", <0.0, 1.0, 0.0>,1.0);            
            //so its not being called too much and slowing down inv changes            
            llSetTimerEvent(8.0);
        }
        if (change & CHANGED_OWNER)
            llResetScript();
    }
    timer()
    {   llSetTimerEvent(0.0);
        llSetText("", <1.0, 1.0, 1.0>,1.0);
        f_assessInventory();        
    }
    state_entry()
    {   f_randomChannel();
        f_assessInventory();
    }
    touch_end(integer num_detected)
    {   gDlgLimiter += 1;
        if (gDlgLimiter == 1)
        {   key av = llDetectedKey(0);
            f_dialogMenu(av, gDrinksList);            
        }
        else if (gDlgLimiter >= 2) //3)
            f_dialogNullify();
    }
    listen(integer channel, string name, key id, string message)
    {   integer index = llListFindList(gDrinksList, [message]);
        if (index == -1)
        {   gChannelNoise++;
            if (gDebug)
                llOwnerSay("FYI - INVALID MESSAGE DETECTED ON THIS CHANNEL:\ngDlgChannel: "+(string)gDlgChannel+"\ngChannelNoise/gChannelNoiseMax = "+(string)gChannelNoise+"/"+(string)gChannelNoiseMax+"\nFrom: "+name+" [key: "+(string)id+"]");
            if (gChannelNoise >= gChannelNoiseMax)
                f_randomChannel();
            return;
        }
        string drink = llGetInventoryName(INVENTORY_OBJECT, index);
        if (drink != "")
        {   f_dialogNullify();            
            if ( (gMsgResponseA != "") || (gMsgResponseB != "") )
                llSay(0, gMsgResponseA+" "+name+" "+gMsgResponseB);
            llGiveInventory(id, drink);
            if (gDebug > 1)
                llOwnerSay("drink: "+drink+" was given to: "+name+" [key: "+(string)id+"]");
        }
        else
        {   // SHOULD never happen
            llOwnerSay("ERROR: The bar has no drinks!!!..or somthing else bad happened..");
        }
    }
}