Dispenser Vendor

From Second Life Wiki
Revision as of 19:56, 24 January 2015 by ObviousAltIsObvious Resident (talk | contribs) (<lsl> tag to <source>)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Created by Kira Komarov. Used a Unix time-stamp converter from Void Singer.

Introduction

This is a simple dispenser vendor script I created for Raphael Debs in Second Life. The requirements were to create a primitive that will dispense a random item from the inventory when a certain amount of money is paid into the primitive. After that, the script should remove the item from inventory and update the overhead text, indicating the remaining quantities of items.

I also went the extra mile and made the script keep track of buyers. You may click the vendor primitive in order to get a list of buyers, as well as the time and date that they bought an item from the dispenser.

Setup

  • Set the price of the item at the top of the script by modifying the constant:
integer PRICE = 0;

to a value above 0.

  • Drop the script in a primitive, along with the objects that you want to sell.

The script will then ask for permissions to debit money and the vendor should be functional.

Notes

  1. If you want to add items to the vendor, open the primitive's contents and add the objects. After that, reset the script.
  2. Hacks: If you want to change the displayed text, simply look at the strings in the code below and change them to something that suits your needs. For example, you could change:
 llSetText("Available items: " + (string)llGetListLength(items), <1,1,1>, 1.0);

to

 llSetText("Remaining items: " + (string)llGetListLength(items), <1,1,1>, 1.0);

So that the text displayed above the vendor contains "Remaining items" instead of "Available items". The same applies to all strings in the script.

Code

//////////////////////////////////////////////////////////
// [K] Kira Komarov - 2011, License: GPLv3              //
// Please see: http://www.gnu.org/licenses/gpl.html     //
// for legal details, rights of fair usage and          //
// the disclaimer and warranty conditions.              //
//////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////
//                   CONFIGURATION                      //
//////////////////////////////////////////////////////////

// This represents the value of one item in the 
// dispenser. Please set this to some sensible non-zero
// value or the script will not proceed.
integer PRICE = 10;
                    
//////////////////////////////////////////////////////////
//                  END CONFIGURATION                   //
//////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// The following is an import function from Void Singer. The original URL: //
// http://wiki.secondlife.com/wiki/Stamp2UnixInt and                       //
/////////////////////////////////////////////////////////////////////////////
/*//--                       Anti-License Text                         --//*/
/*//     Contributed Freely to the Public Domain without limitation.     //*/
/*//   2009 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ]   //*/
/*//  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*//--                                                                 --//*/

list uUnix2StampLst( integer vIntDat ){
    if (vIntDat / 2145916800){
        vIntDat = 2145916800 * (1 | vIntDat >> 31);
    }
    integer vIntYrs = 1970 + ((((vIntDat %= 126230400) >> 31) + vIntDat / 126230400) << 2);
    vIntDat -= 126230400 * (vIntDat >> 31);
    integer vIntDys = vIntDat / 86400;
    list vLstRtn = [vIntDat % 86400 / 3600, vIntDat % 3600 / 60, vIntDat % 60];
 
    if (789 == vIntDys){
        vIntYrs += 2;
        vIntDat = 2;
        vIntDys = 29;
    }else{
        vIntYrs += (vIntDys -= (vIntDys > 789)) / 365;
        vIntDys %= 365;
        vIntDys += vIntDat = 1;
        integer vIntTmp;
        while (vIntDys > (vIntTmp = (30 | (vIntDat & 1) ^ (vIntDat > 7)) - ((vIntDat == 2) << 1))){
            ++vIntDat;
            vIntDys -= vIntTmp;
        }
    }
    return [vIntYrs, vIntDat, vIntDys] + vLstRtn;
}
/////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////
//                     INTERNALS                        //
//////////////////////////////////////////////////////////

list items = [];
list buyers = [];

default
{
    state_entry()
    {
        if(!PRICE) {
            llOwnerSay("The price is set to 0, please edit the script and set a price in the configuration section.");
            return;
        }
        
        integer itra;
        for(itra=0, items = []; itra<llGetInventoryNumber(INVENTORY_OBJECT); ++itra) {
            items += llGetInventoryName(INVENTORY_OBJECT, itra);
        }
        
        if(llGetListLength(items))
            llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
    }
    run_time_permissions(integer perm)
    {
        if(perm & PERMISSION_DEBIT) {
            llSetText("Available items: " + (string)llGetListLength(items), <1,1,1>, 1.0);
            state vend;
        }
    }
}

state vend
{
    state_entry() {
        llSetPayPrice(PRICE, (list)PRICE);
    }

    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        integer itra;
        llOwnerSay("=================== BUYERS ===================");
        for(itra=0; itra<llGetListLength(buyers); itra+=2) {
            list stm = uUnix2StampLst(llList2Integer(buyers, itra+1));
            llOwnerSay(llList2String(buyers,itra) + " @ " + llDumpList2String(llList2List(stm, 0, 2), "-") + " " + llDumpList2String(llList2List(stm, 3, 5), ":"));
        }
        llOwnerSay("=================== BUYERS ===================");
    }
        
    money(key id, integer amount) {
        if(amount != PRICE) {
            llInstantMessage(id, "Sorry, L$" + (string)amount + " is not the correct price for an item. The correct price is L$" + (string)PRICE);
            llGiveMoney(id, amount);
            return;
        }
        integer itra = (integer)llFrand(llGetListLength(items));
        string item = llList2String(items, itra);
        items = llDeleteSubList((items = []) + items, itra, itra);
        llGiveInventory(id, item);
        buyers += llKey2Name(id);
        buyers += llGetUnixTime();
        for(itra=0; itra<llGetInventoryNumber(INVENTORY_OBJECT); ++itra) {
            if(llGetInventoryName(INVENTORY_OBJECT, itra) == item) {
                llRemoveInventory(item);
                jump done;
            }
        }
@done;
        llSetText("Available items: " + (string)llGetListLength(items), <1,1,1>, 1.0);
    }
}