This is part of the cashier project and an implementation of a till.
The till contains the script in the code section below along with the all the available currency.
////////////////////////////////////////////////////////// // (c) Wizardry and Steamworks - 2013, License GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html // // for legal details, rights of fair usage and // // the disclaimer and warranty conditions. // ////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueGet(string var, string kvp) { list dVars = llParseString2List(kvp, ["&"], []); do { list data = llParseString2List(llList2String(dVars, 0), ["="], []); string k = llList2String(data, 0); if(k != var) jump continue; return llList2String(data, 1); @continue; dVars = llDeleteSubList(dVars, 0, 0); } while(llGetListLength(dVars)); return ""; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueSet(string var, string val, string kvp) { list dVars = llParseString2List(kvp, ["&"], []); if(llGetListLength(dVars) == 0) return var + "=" + val; list result = []; do { list data = llParseString2List(llList2String(dVars, 0), ["="], []); string k = llList2String(data, 0); if(k == "") jump continue; if(k == var && val == "") jump continue; if(k == var) { result += k + "=" + val; val = ""; jump continue; } string v = llList2String(data, 1); if(v == "") jump continue; result += k + "=" + v; @continue; dVars = llDeleteSubList(dVars, 0, 0); } while(llGetListLength(dVars)); if(val != "") result += var + "=" + val; return llDumpList2String(result, "&"); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2012 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// list wasInsertSort(list toSort) { list sorted = []; @next_element; integer n = llList2Integer(toSort, 0); toSort = llDeleteSubList(toSort, 0, 0); integer s = llGetListLength(sorted)-1; if(s == -1) { sorted += n; jump next_element; } do { integer sn = llList2Integer(sorted, s); if(n < sn) jump continue; sorted = llListInsertList(sorted, (list)n, s+1); if(llGetListLength(toSort)) jump next_element; return sorted; @continue; } while(--s>-1); sorted = llListInsertList(sorted, (list)n, 0); if(llGetListLength(toSort)) jump next_element; return sorted; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueEncode(list kvp) { if(llGetListLength(kvp) < 2) return ""; string k = llList2String(kvp, 0); kvp = llDeleteSubList(kvp, 0, 0); string v = llList2String(kvp, 0); kvp = llDeleteSubList(kvp, 0, 0); if(llGetListLength(kvp) < 2) return k + "=" + v; return k + "=" + v + "&" + wasKeyValueEncode(kvp); } integer totalPaid = 0; key customer = NULL_KEY; list currency = []; default { state_entry() { integer i = llGetInventoryNumber(INVENTORY_OBJECT)-1; do { currency += (integer)wasKeyValueGet("money", llGetInventoryName(INVENTORY_OBJECT, i)); } while(--i>-1); currency = wasInsertSort(currency); state wait; } } state wait { touch_start(integer num) { totalPaid = 0; llSetObjectDesc(wasKeyValueSet("total", "0", llGetObjectDesc())); llSetObjectDesc(wasKeyValueSet("key", llDetectedKey(0), llGetObjectDesc())); state enter; } } state enter { state_entry() { integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)); key a = wasKeyValueGet("key", llGetObjectDesc()); llListen(comChannel, "", a, ""); llTextBox(a, "\nPlease enter product price:\n", comChannel); } touch_start(integer num) { key a = wasKeyValueGet("key", llGetObjectDesc()); if(a != llDetectedKey(0)) return; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)); llListen(comChannel, "", a, ""); llDialog(a, "Enter another product?", [ "Yes", "No" ], comChannel); } listen(integer channel, string name, key id, string message) { if(message == "Yes") { llTextBox(id, "\nPlease enter product price:\n", channel); return; } if(message == "No") jump final; llSetObjectDesc(wasKeyValueSet("total", (string)((integer)message+(integer)wasKeyValueGet("total", llGetObjectDesc())), llGetObjectDesc())); llDialog(id, "Enter another product?", [ "Yes", "No" ], channel); return; @final; state totals; } } state totals { state_entry() { llSay(0, "The total is: " + wasKeyValueGet("total", llGetObjectDesc())); llSensorRepeat("", "", ACTIVE|SCRIPTED, 10, TWO_PI, 1); } touch_start(integer num) { key a = wasKeyValueGet("key", llGetObjectDesc()); if(a != llDetectedKey(0)) return; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)); llListen(comChannel, "", a, ""); llDialog(a, "Cancel the transaction?", [ "Cancel" ], comChannel); } listen(integer channel, string name, key id, string message) { if(message == "Cancel") state wait; } sensor(integer num) { --num; do { totalPaid += (integer)wasKeyValueGet("money", llDetectedName(num)); } while(--num>-1); customer = llGetOwnerKey(llDetectedKey(0)); // Determine whether customer has paid an amount equal or more than the required payment. integer total = (integer)wasKeyValueGet("total", llGetObjectDesc()); if(totalPaid < total) { totalPaid = 0; // If not, bail out and keep looking for money. return; } // They did, so thank the customer and remove the sensor. llSay(0, "Thank you! Here is your change..."); llSensorRemove(); // Delete (take) the money the customer paid. integer comChannel = (integer)("0x8" + llGetSubString(llGetCreator(), 0, 6)); integer m = llGetListLength(currency)-1; do { llRegionSay(comChannel, wasKeyValueEncode(["owner", customer, "amount", llList2String(currency, m), "money", "die"])); } while(--m>-1); // Now give the customer the difference. integer cashReturn = totalPaid - total; do { integer i = llGetListLength(currency)-1; do { integer rp = llList2Integer(currency, i); if(rp > cashReturn) jump continue; llGiveInventory(customer, wasKeyValueEncode(["money", (string)rp])); cashReturn -= rp; @continue; } while(--i>-1); } while(cashReturn != 0); state wait; } }