Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Tip Jar Help

Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-24-2008 19:30
Hey. im trying to script a tip jar that will split the profit with a percentage setup in a config file. but i want it to be able to split the profit between, up to, 4 people, and i want to be able to change the name of the tip jar in the config file... Here is what i have so far.. but it wont work..
CODE

key line1;
key line2;
key line3;
key line4;
string line5;

key keyactive;
string nameactive;

key splitwith;
integer percentage;

default
{
on_rez(integer param)
{
llResetScript();
}

state_entry()
{
line1 = llGetNotecardLine("config",0);
line2 = llGetNotecardLine("config",0);
llSetText("Tip jar intactive", <1,1,1> ,1.0);
}

dataserver(key queryid, string data)
{
if (queryid == line1)
{
list templist = llParseString2List(data, [" "],[]);
splitwith = (key) llList2String(templist,0);
percentage = (integer) llList2String(templist,1);
llOwnerSay("Profit will be split with:
"+llKey2Name(splitwith)+". Person will receive: "+(string)
percentage+"%.");

llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
}

run_time_permissions (integer perm)
{
if (perm == PERMISSION_DEBIT)
{
state active;
} else
{
llOwnerSay("I need those permissions. Please reset me to try
again.");
}
}

}

state active
{
on_rez(integer param)
{
llResetScript();
}

state_entry()
{
line5 = llGetNotecardLine("config",1);
llSetPayPrice(25, [25, 50, 75, 100]);
}


touch_start(integer nr)
{
key toucher = llDetectedKey(0);
if (!llSameGroup(toucher))
{
return;
}

if (toucher == keyactive)
{
keyactive = NULL_KEY;
nameactive = "";
llSetText("Tip jar unassigned",<1,1,1>,1.0);
llSetPayPrice(PAY_HIDE, [PAY_HIDE, PAY_HIDE,
PAY_HIDE, PAY_HIDE]);
} else
{
keyactive = toucher;
nameactive = llKey2Name(toucher);
llSetText(nameactive+"'s tip jar",<1,1,1>, 1.0);
llSetPayPrice(PAY_DEFAULT, [PAY_DEFAULT,
PAY_DEFAULT, PAY_DEFAULT, PAY_DEFAULT]);
}

}

money(key id, integer amount)
{
integer split = llRound((amount * percentage) / 100);
integer tipreceiver = amount - split;
llGiveMoney(keyactive, tipreceiver);
llGiveMoney(splitwith, split);

llSay(0,"Thank you for your donation.");
}
}




and this is the error i get.


Object: NULL_KEY destination for llGiveMoney().

any ideas on how to get this working?/ im stumped.
Klug Kuhn
Registered User
Join date: 7 Sep 2007
Posts: 126
12-24-2008 21:14
From the error it means the giving money avatar key is empty, you could add a line to debug, e.g.:

money(key id, integer amount)
{
integer split = llRound((amount * percentage) / 100);
integer tipreceiver = amount - split;

llOwnerSay("keyactive = "+(string)keyactive+", splitwith = "+(string)splitwith); // added debug line

llGiveMoney(keyactive, tipreceiver);
llGiveMoney(splitwith, split);

llSay(0,"Thank you for your donation.";);
}
}


Then you should be able to know which key was missing (or both etc.) to debug :) It's probably just the notecard reading incorrect, but i've not tested it in-world tho.
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-24-2008 21:47
ok man.. i added the Debug line and it gave me this
Object: keyactive = 7da3ec84-4f2f-444a-beea-da93839bc408, splitwith = //Avatar
Sleepy Xue
I script Pretty HUDs
Join date: 22 Jun 2008
Posts: 57
12-24-2008 21:54
I just scripted a tip jar and posted it for the world. =]

/54/3b/299445/1.html
_____________________
I script pretty HUDs.
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
12-24-2008 23:54
From: Zaine Swords
ok man.. i added the Debug line and it gave me this
Object: keyactive = 7da3ec84-4f2f-444a-beea-da93839bc408, splitwith = //Avatar
And did it correctly identify splitwith in
CODE
 llOwnerSay("Profit will be split with: 
"+llKey2Name(splitwith)+". Person will receive: "+(string)
percentage+"%.");
when it read the notecard in state default?
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-26-2008 18:31
no it did not.
if i can get this thing to split the percentage with at least 2 ppl that would be great. and i want to be able to cahnge the name of the tip jar through the config file aswell but havnt figured out a way for it to work either. any help would be great.
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-27-2008 00:00
ok.. While waiting for some help here, i have been reading up a lil more on scripting. particularly on how to get the reading of the notcard to work the way i want it to. and what i have found out that the way i was trying to do it orginoly isnt going to work at all.. cause all im telling the script to do it pull the notecard line like 5 diffrent times. now if im figureing this out right, i only need to do it twice. once for the string, and once for the key. no i have already pulled from the key but havnt for the string. at least not correctly. if there is a flaw in this please let me know.
Nicolette Beebe
Registered User
Join date: 8 Feb 2007
Posts: 18
12-27-2008 02:06
yeah this one looks so full of problems I dont know where to begin.

first you have only one global variaiable for a key to split with and thier percent

another problem i see is it appears line 1 = the first notecard line
then line 2 reads notecard line 1 again

then further down i see line5? it reads line 2 of the notecard but what does it do? Nothing that i can see.

then there is the issue of we can not see your notecard. but from the look of the script line1 of irt should be the av key followed my one space then a percent in the form of an integer.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
12-27-2008 11:06
I wouldn't be THAT down on it. It looks like a pretty good start with a script that splits between two people (I think it is supposed to be between the person in the notecard and the last person with the group active who touched the prim/object).

The place the OP is running into trouble is in adding more people into the mix. All the reading should be done in the first state, BEFORE going into the 'active' state. And you're going to have to decide WHEN to go into the 'active' state (hint: once all the keys have been read and/or you hit the end of the notecard...?). Now try to think about how to read each of the keys in a consistent way; they should all look ABOUT the same.

I hope that is a good start. If you run into specific questions be sure to ask away.

EDIT: Oh. One more suggestion: if you know what a flow chart is, you might sketch one out before going back to the code. It can be very helpful.
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-28-2008 11:15
ok.. after much try and working, i am more confiused then ever now. i have had a few people try and write me a script that i'm needing. they either werent exactly what i was looking for or didnt work and both. dont get me wrong im thankful for the efforts and i want to thank those who have tried. but one person has brought to my attention, weather he knew it or not, that one of my requests was mis worded. i dont want the object name changed through the config but i want the SetText changed through the config. i thought i had this all figured out and then i got lost and confuesed again.. lol. sorry all, but any help would be great.
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-28-2008 22:11
ok.. i went back to the basic's of this script. i took out alot of things that i did find out wern't needed. here it is.
CODE

key line1;

key keyactive;
string nameactive;

key splitwith;
integer percentage;

default
{
on_rez(integer param)
{
llResetScript();
}

state_entry()
{
line1 = llGetNotecardLine("config",0);
llSetText("Tip jar intactive", <1,1,1> ,1.0);
}

dataserver(key queryid, string data)
{
if (queryid == line1)
{
list templist = llParseString2List(data, [" "],[]);
splitwith += (key) llList2String(templist,0);
percentage += (integer) llList2String(templist,1);
llOwnerSay("Profit will be split with:
"+llKey2Name(splitwith)+". Person will receive: "+(string)
percentage+"%.");

llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
}

run_time_permissions (integer perm)
{
if (perm == PERMISSION_DEBIT)
{
state active;
} else
{
llOwnerSay("I need those permissions. Please reset me to try
again.");
}
}

}

state active
{
on_rez(integer param)
{
llResetScript();
}

state_entry()
{
llSetText("Tip jar unassigned",<1,1,1>,1.0);
llSetPayPrice(25, [25, 50, 75, 100]);
}


touch_start(integer nr)
{
key toucher = llDetectedKey(0);
if (!llSameGroup(toucher))
{
return;
}

if (toucher == keyactive)
{
keyactive = NULL_KEY;
nameactive = "";
llSetText("Tip jar unassigned",<1,1,1>,1.0);
llSetPayPrice(PAY_HIDE, [PAY_HIDE, PAY_HIDE,
PAY_HIDE, PAY_HIDE]);
} else
{
keyactive = toucher;
nameactive = llKey2Name(toucher);
llSetText(nameactive+"'s tip jar",<1,1,1>, 1.0);
llSetPayPrice(PAY_DEFAULT, [PAY_DEFAULT,
PAY_DEFAULT, PAY_DEFAULT, PAY_DEFAULT]);
}

}

money(key id, integer amount)
{
integer split = llRound((amount * percentage) / 100);
integer tipreceiver = amount - split;
llGiveMoney(keyactive, tipreceiver);
llGiveMoney(splitwith, split);

llSay(0,"Thank you for your donation.");
}
}




and here is the config that goes along with it.

CODE

da3ec84-4f2f-444a-beea-da93839bc408 5
a79d2253-72e3-4ff0-8173-b55e8c61b790 5
"Tip Jar"


as you can see from the config, the key goes in with a space and then the percentage of what that person will get. now i would like to just be able to put the avatar's name in there but i got a feeling thats a whole nother part of scritping.. if anyone can help me from here that would be great. thanks.
Yingzi Xue
Registered User
Join date: 11 Jun 2008
Posts: 144
12-29-2008 03:18
I believe string = llKey2Name(key) will give you the name of the prim or avatar based on the key.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
12-29-2008 04:17
From: Yingzi Xue
I believe string = llKey2Name(key) will give you the name of the prim or avatar based on the key.

If--when the function is called--the object or avatar is in the same sim as the prim with the script, yes. Otherwise you can't get the name of an object and you need this to get the name of an avatar: http://wiki.secondlife.com/wiki/LlRequestAgentData
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-29-2008 09:36
ok so llKey2Name uses the key, what if i use llName2String. will i be able to use the name of the Avatar or prim and it work and if so, how will that wok? would i have to be on the same sim as it or not.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
12-29-2008 10:25
From: Zaine Swords
ok so llKey2Name uses the key, what if i use llName2String. will i be able to use the name of the Avatar or prim and it work and if so, how will that wok? would i have to be on the same sim as it or not.

Ahhh...I see what you are asking. You'd like to put the name of the avatar in the notecard. For that you'll have to do a reverse lookup. There's no built-in function to do that, but there are a few decent services out there that will. For example, check out http://w-hat.com/name2key/
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
12-29-2008 10:31
There is no llName2String function, nor is it needed. llKey2Name returns a string variable. And yes, you can use the avatar name as a variable anywhere you like. Since all avatar names in SL are unique, a name makes a perfectly good identifier. You might as well type it on your notecard, unless you really need the avatar's key for some reason.

To use the llKey2Name function to get an avatar's name, yes, your script does need to be running in the same sim. That's not going to be a problem for your tipjar, obviously.
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-29-2008 10:56
ok yes.. so i can put that part of the script in my script and all i have to do is type in the name of the person i want to have a percentage of and it will find the avatar key itself. and also im still trying to find out how i can have more than 1 person get a percentage of the tips. would be nice to have it able to have up to 5 but will be happy with 2. and still trying to figure out how to do the llSetText from the config aswell.
Klug Kuhn
Registered User
Join date: 7 Sep 2007
Posts: 126
12-29-2008 15:42
Just a question about the notecard reading. Is it really necessary to read the configs from a notecard? Because you're writing the script, it's easier to have all settings defined in the script directly... Unless you're setting it no mod to transfer, it's gonna be an easier second life if no notecard reading. If this is the case, i could post a in-world tested script here where possible :)
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-29-2008 16:42
yea i was going to set it no mod cause i have friends who dont no anything about scripting so i want to make it easy for them.. and im really not that great with scripting either.. i can figure some of it out but not all which is why i am here :D.
Klug Kuhn
Registered User
Join date: 7 Sep 2007
Posts: 126
12-30-2008 16:45
I've made a little tip jar which should be able to meet your requirement. :) To use:

1. ➛ drop the tip jar script into the tip jar.

2. ➛ make a notecard named exactly [ Config ] and input the name and commission details as follow, e.g.:

begin

klug kuhn / 3
zaine swords / 5

end

> put a "begin" and an "end" for the first and last line on the config notecard
> in between, put the beneficiary names, followed by a /
> then the commission in percentage after the /
> you may put as many beneficiary as you like upon the script memory
> the names will be converted to the UUID from the w_hat website

3. ➛ touch the tip jar and there are 3 options:

System ON - enable tip jar
System OFF - disable tip jar
Upload > - upload the config notecard, the [ Config ] must be in the tip jar's content


CODE

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/_/_/_/_/_/_/ Tip Jar Script _/_/_/_/_/_/_/_/_/_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
list beneficiary_list = []; // a list to store all beneficiarys
list commission_list = []; // a list to store all commissions
key toucher = NULL_KEY; // who touches the tip jar
integer listen_num = -1; // a listen handler for the option menu
key gSetupQueryId = NULL_KEY; // config notecard handler
integer gSetupNotecardLine = 0; // config notecard line
integer gLine_number = 0; // config notecard line number
string gSetupNotecardName = ""; // config notecard name
string converting_name = ""; // the beneficiary name converting to UUID from w_hat
integer name_counter = 0; // a counter used in the name convertion
key reqid = NULL_KEY; // w_hat handler
// ====================================
integer check_config_notecard()
{ // return 1 if found; 0 if not found;
integer i;
for (i = 0; i <= llGetInventoryNumber(INVENTORY_NOTECARD) - 1; i++)
{
string checking_notecard = llGetInventoryName(INVENTORY_NOTECARD,i);
if (checking_notecard == "Config")
{
gSetupNotecardName = "Config";
return 1;
}
}

llOwnerSay(" *NOTICE* No notecard [ Config ] found in content!");
return 0;
}

// ====================================
default
{ // get the debt permission before going further
state_entry()
{
llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
}
run_time_permissions(integer perm)
{
if(perm & PERMISSION_DEBIT)
{
llSetPayPrice(PAY_HIDE, [PAY_HIDE,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
llSay(0," permission granted. Touch to begin ...");
state ready;
}
else
{
llOwnerSay(" please 'Grant' the permission to continue ...");
llResetScript();
}
}
on_rez(integer int)
{
llResetScript();
}
}
state ready
{ // when the tip jar is ready
state_entry()
{
}
changed(integer change)
{
if (change & CHANGED_OWNER)
llResetScript();
}
touch_start(integer int)
{
toucher = llDetectedKey(0);
if (llSameGroup(toucher))
{
integer menu_chan = 0 - (integer)llFrand(2147483647);
listen_num = llListen(menu_chan,"", toucher,"");
llDialog(toucher, "Select option:", ["System ON","System OFF","Upload >"], menu_chan);
llSetTimerEvent(60.0);
}
else
{
llSay(0," sorry, group access only.");
}
}
listen(integer channel, string name, key id, string message)
{
if (message == "System ON")
{
llSetPayPrice(PAY_DEFAULT, [PAY_DEFAULT,PAY_DEFAULT, PAY_DEFAULT, PAY_DEFAULT]);
llSetText(llKey2Name(llGetOwner())+"'s Tip Jar",<1.0,1.0,1.0>, 1.0);
llSay(0," system is ON.");
}
else if (message == "System OFF")
{
llSetPayPrice(PAY_HIDE, [PAY_HIDE,PAY_HIDE,PAY_HIDE,PAY_HIDE]);
llSetText("Tip jar unassigned",<1.0,1.0,1.0>,1.0);
llSay(0," system is OFF.");
}
else if (message == "Upload >")
{
if (check_config_notecard())
state upload;
}
llSetTimerEvent(0.1);
}
timer()
{
llListenRemove(listen_num);
llSetTimerEvent(0.0);
}
money(key customer, integer amt)
{
integer i = 0;
for (i = 0; i < llGetListLength(beneficiary_list); i++)
{
key name = (key)llList2String(beneficiary_list,i);
integer comm = (integer)((float)amt * (float)llList2String(commission_list,i) / 100.0);

if ( (name != NULL_KEY) && (comm > 1) )
{
llGiveMoney(name,comm);
}
}
}
}
state upload
{
state_entry()
{
llSetTimerEvent(0.0);
llSay(0," uploading, please wait ...");
gSetupNotecardLine = 0;
gSetupQueryId = llGetNumberOfNotecardLines(gSetupNotecardName);
}
dataserver(key queryId, string data)
{
if(queryId == gSetupQueryId)
{
if(data != EOF)
{
string line = llStringTrim(data,STRING_TRIM);

if ( (line != "") && (line != "1") )
{
list temp_list = llParseString2List(data, ["/"], []);
string temp_list0 = llToLower(llStringTrim(llList2String(temp_list, 0),STRING_TRIM)); // beneficiary name
integer temp_list1 = (integer)(llStringTrim(llList2String(temp_list, 1),STRING_TRIM)); // commission

if (temp_list1 != 0)
{
if (temp_list0 != "")
{
beneficiary_list += temp_list0;
}

if (temp_list1 > 0)
{
commission_list += temp_list1;
}
}
else if (llToLower(line) == "end")
state comm;
}

gSetupQueryId = llGetNotecardLine(gSetupNotecardName,++gSetupNotecardLine);
}
}
}
}
state comm
{
state_entry()
{
converting_name = llList2String(beneficiary_list,name_counter);
if (converting_name != "")
state w_hat;
else
{
llSay(0," upload completed.");
state ready;
}
}
}
state w_hat
{
state_entry()
{
reqid = llHTTPRequest("http://w-hat.com/name2key"+"?terse=1&name="+llEscapeURL(converting_name),[],"" );
}
http_response(key id, integer status, list meta, string body)
{
if ( ( id != reqid ) || ( status == 499 ) || ( status != 200 ) || ( (key)body == NULL_KEY ) )
llSay(0," sorry, cannot use name [ "+converting_name+" ]. Please try again later.");
else
beneficiary_list = llListReplaceList(beneficiary_list,[(key)body],name_counter,name_counter);

name_counter += 1;
state comm;
}
}
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
12-30-2008 21:54
hey man thanks, ut, err... dont know how to say this but... it doesnt split the percentage like it should at all...

ok. if a person tips $10 then the owner gets no percentage. so i tipped 20L it said i paid the person logged into the jar, i got paid $2, then 4 again, then 4. and the other person, who isnt even in the Config file anymore, got paid 4. and yes i did do the upload first after changing the notcard. other than that it works great. :D and i also got a script error..

NULL_KEY destination for llGiveMoney().

i dont understand it.
Sleepy Xue
I script Pretty HUDs
Join date: 22 Jun 2008
Posts: 57
12-31-2008 15:34
What was wrong with the one I scripted (link in earlier post)?
_____________________
I script pretty HUDs.
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
01-01-2009 16:27
it wouldnt let you log in it. you clicked and touched it but nothing happened.. still said Tip jar unassingned.
Zaine Swords
Registered User
Join date: 26 Nov 2008
Posts: 47
01-01-2009 20:06
ok the last tip jar script i have it just stopped working.. it is something to do with the new upgrade LL did or something?