Dispenser Vendor
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
- If you want to add items to the vendor, open the primitive's contents and add the objects. After that, reset the script.
- 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);
}
}