/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2011 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // CONFIGURATION // ////////////////////////////////////////////////////////// // // string THANKS_MESSAGE = "Thank you for your tip %n%! %m% greatly appreciates it!"; string TIPPER_TOUCH_MESSAGE = "Hello %n%! This tipjar belongs to %m%. If you like my work, please consider giving me a tip. To tip me, please right-click my tipjar and select Pay and enter the ammount you would like to tip me with. Thank you!"; string TIPPER_DIALOG_MESSAGE = "Hello, %n%! Please choose an option from the ones below:\nJoin - will send you a group invite.\nGift - will send you a free gift!"; string OVERHEAD_MESSAGE = "%m%'s Tipjar, any tip is welcome!"; string LOGOUT_MESSAGE = "%m%'s Tipjar is logging off, please standby to receive your share %n%..."; list TIPPER_TOUCH_MENU = [ "◆ Join ◆", "◆ Gift ◆" ]; key INVITE_GROUP_KEY = "004079ff-e1b0-c671-dd5e-eb4f6e361684"; string INVITE_GROUP_MESSAGE = "Please join the group %n%! To do so, please click the link in your history window (ctrl+h):"; list PAY_BUTTONS = [ 20, 40, 60, 80 ]; integer EXCLUDE_ACCESS_FROM_SPOILS = 1; integer TIPJAR_ROAMING = 1; integer ROAM_INTERVAL = 30; integer ROAM_RANGE = 10; // // // END CONFIGURATION // ////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // INTERNALS // /////////////////////////////////////////////////////////////////////////// string tokenSubstitute(string input, key id) { list kSubst = llParseString2List(input, ["%"], [""]); integer itra; for(itra=0; itra * llGetMass(), 0); llSetStatus(STATUS_PHYSICS, bool); llSetStatus(STATUS_PHANTOM, bool); } list spoilMemberNames = []; list spoilMemberKeys = []; list spoilPercents = []; list tippers = []; list tipperAmounts = []; list accessListNames = []; list accessListKeys = []; string activeAvatarName = ""; key activeAvatarKey = NULL_KEY; key sQuery = NULL_KEY; integer sLine = 0; integer readNotecard = 0; integer comHandleTiper = 0; integer comHandleSpoiler = 0; integer allSpoils = 0; vector landingPoint; rotation landingRotation; list avPositions = []; integer positionRoam = 0; integer targetID = 0; integer roaming = 0; default { state_entry() { physics(FALSE); accessListNames = []; accessListKeys = []; sLine = 0; readNotecard = 0; activeAvatarName = ""; activeAvatarKey = NULL_KEY; llSetText("Tipjar loading access, please wait...", <1,1,1>, 1); if(llGetInventoryType("Tipjar Access") == INVENTORY_NOTECARD) jump found_access; llSetText("No access list. Please revise your configuration.", <1,1,1>, 1); llInstantMessage(llGetOwner(), "Failed to find Tipjar Access card. Please add a notecard called Tipjar Access and configure it apropriately."); return; @found_access; sQuery = llGetNotecardLine("Tipjar Access", sLine); llSetTimerEvent(5.0); } changed(integer change) { if(change & CHANGED_INVENTORY) llResetScript(); } on_rez(integer num) { physics(FALSE); } timer() { if(readNotecard) { llSetTimerEvent(.0); llSetText("Tipjar idle. Please click me to activate.", <1,1,1>, 1); return; } llSetTimerEvent(5.0); } dataserver(key id, string data) { if(id != sQuery) return; if(data == EOF) { readNotecard = 1; return; } if(data == "") jump next_line; list accessParse = llParseString2List(data, ["#"], [""]); accessListNames += llList2String(accessParse, 0); accessListKeys += llList2Key(accessParse, 1); @next_line; sQuery = llGetNotecardLine("Tipjar Access", ++sLine); } touch_start(integer num) { if(~llListFindList(accessListKeys, (list)llDetectedKey(0))) { activeAvatarName = llDetectedName(0); activeAvatarKey = llDetectedKey(0); state init; } } } state init { state_entry() { allSpoils = 0; tippers = []; tipperAmounts = []; spoilMemberNames = []; spoilMemberKeys = []; spoilPercents = []; readNotecard = 0; sLine = 0; llSetText("Tipjar initalizing, please wait...", <1,1,1>, 1); if(llGetInventoryType("Tipjar Spoils") == INVENTORY_NOTECARD) jump found_spoils; llSetText("Falied! Please check Tipjar Spoils notecard.", <1,1,1>, 1); llInstantMessage(llGetOwner(), "Failed to find Tipjar Spoils card. Please add a notecard called Tipjar Spoils and configure it apropriately."); return; @found_spoils; sQuery = llGetNotecardLine("Tipjar Spoils", sLine); landingPoint = llGetPos(); landingRotation = llGetRot(); llSetTimerEvent(5.0); } changed(integer change) { if(change & CHANGED_INVENTORY) llResetScript(); } timer() { if(readNotecard) { llSetTimerEvent(.0); integer itra; integer percents = 0; for(itra=0; itra 100) { llOwnerSay("The percents in your Tipjar Spoils notecard add up to " + (string)percents + "%. They should add up to 100%. Please check your setup again."); state default; } llRequestPermissions(llGetOwner(), PERMISSION_DEBIT); return; } llSetTimerEvent(5.0); } listen(integer channel, string name, key id, string message) { if(id != activeAvatarKey) return; if(message == "[ Confirm ]") { llListenRemove(comHandleSpoiler); state tipjar; } llResetScript(); } dataserver(key id, string data) { if(id != sQuery) return; if(data == EOF) { readNotecard = 1; return; } if(data == "") jump next_line; list spoilList = llParseString2List(data, ["#"], [""]); if(EXCLUDE_ACCESS_FROM_SPOILS && ~llListFindList(accessListNames, (list)llList2String(spoilList, 0))) jump next_line; spoilMemberNames += llList2String(spoilList, 0); spoilMemberKeys += llList2Key(spoilList, 1); spoilPercents += llList2String(spoilList, 2); @next_line; sQuery = llGetNotecardLine("Tipjar Spoils", ++sLine); } run_time_permissions(integer perm) { if(perm & PERMISSION_DEBIT) { integer comChannel = ((integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; comHandleSpoiler = llListen(comChannel, "", activeAvatarKey, ""); integer itra; string confirmText; for(itra=0; itra < llGetListLength(spoilMemberNames); ++itra) { confirmText += llList2String(spoilMemberNames, itra) + " gets " + llList2String(spoilPercents, itra) + "%.\n"; } confirmText += "\n\n"; llDialog(activeAvatarKey, "Tipjar: Please revise and confirm the spoils distribution:\n\n" + confirmText, [ "[ Confirm ]", "[ Reject ]" ], comChannel); } } } state tipjar { state_entry() { llOwnerSay("Tipjar initialized and ready to be tipped. Good Luck " + activeAvatarName + "!"); llSetPayPrice(100, PAY_BUTTONS); llSetText(tokenSubstitute(OVERHEAD_MESSAGE, activeAvatarKey), <1,1,1>, 1); if(TIPJAR_ROAMING) llSensorRepeat("", "", AGENT, ROAM_RANGE, PI, ROAM_INTERVAL); } sensor (integer num) { if(roaming) return; roaming = 1; integer itra; for(itra=0, avPositions = [], positionRoam = 0; itra, 1); physics(TRUE); moveTo(landingPoint); } at_target(integer tnum, vector targetpos, vector ourpos) { if(tnum != targetID) return; physics(FALSE); llSetPos(landingPoint); llSetRot(landingRotation); state payments; } } state payments { state_entry() { llSetText("Loging out...", <1,1,1>, 1); physics(FALSE); integer remSpoils = allSpoils; integer itra; for(itra=0; itra