Vendor Script problems :(
|
|
Suzanna Soyinka
Slinky Slinky Slinky
Join date: 25 Nov 2005
Posts: 292
|
04-18-2006 11:23
I've written up a little one item vendor script that uses FastPay to use in a sale sign for an item I just released. Regardless, everything about the script works, it asks for debit perms, and it takes money from people and gives it to me. But...for some reason I can't get it to give the item in the inventory of the prim. It doesn't work with UUID or exact object name. I'd appreciate a tip here because its driving me nuts, to me...it looks like the script should work...but it doesn't. Heres my script integer x = 1; integer price = 300; string item = "Item Name Here"; string thank = "Thank you for shopping with us."; default { on_rez(integer total_number) { llResetScript(); llSetStatus(STATUS_BLOCK_GRAB, TRUE); } touch_start(integer num) { llSay(0, "Touch Message"); } state_entry() { llRequestPermissions(llGetOwner(), PERMISSION_DEBIT); } money(key id, integer amount) { llSetPayPrice(PAY_HIDE, [300, 0, 0, 0]); if(amount = price) { llSay(0, thank); llGiveInventory(llDetectedKey(0), item); } } }
I'm sure what I'm doing wrong here is pretty elementary, but I've been banging my head on the Wiki for an hour or so now and found no resolution. Thanks in advance.
|
|
Sky Honey
Coder
Join date: 16 May 2005
Posts: 105
|
04-18-2006 11:56
llGiveInventory(llDetectedKey(0), item); should be llGiveInventory(id, item); llDetectedKey doesn't have a value in the money event. The avatar who clicked the Pay button is passed in the id parameter.
|
|
Kai Venkman
Will script for food...
Join date: 21 Feb 2006
Posts: 43
|
04-18-2006 11:57
Don't you want
if (amount == price)
|
|
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
|
04-18-2006 11:59
cupple things
1 if your setting the pay buttons you dont really need permission debit, that only allows ppl to take money from your account.... it was commonly used to give back change or flat out incorrect amounts, but since your setting the pay price theres no real need for it
2 llSetPayPrice(PAY_HIDE, [300, 0, 0, 0]); instead of 0,0,0 you can use PAY_HIDE and just not show the other buttons at all, you dont want someone paying you 0$ and getting product and you can remove the if (amount == price) line
ok onto the question, inventory is a pain in the butt, in order to sell it you must have it inside the vendor with copy and trasnfer rights (you can set the next owner rights to whatever) so if YOU dont have atleast transfer rights the vendor cant give it away, if you dont have copy rights but do have transfer rights the machine will sell the 1 copy it has
also they have to be called by name only, and must appear in the contents of the prim with the script in it ... thats probally your problem there
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
04-18-2006 12:00
llDetectedKey only works on touch, sensor or collision. It won't work in money. You already have the key of the person who paid you - money(key id, integer amount). So just use that id as the destination key to give the item to. A couple of other issues... You should probably call llSetPayprice in state_entry. The way you have it now, a new script in a new prim will only set the fast pay price *after* it gets paid the first time. So the first person who buys the item won't get the fast pay dialog, they'll get the normal pay dialog. Related to the above... I always put in code in the money event that refunds the av if they pay the wrong amount. The first person could pay you any amount, because fast pay isn't set up, your money event will go "the amount paid isnt the price of the item", and won't give him the item. It won't refund him the money either. So now you have a customer who paid into this object, and didn't get anything in return. They won't be happy  Even with fast pay set in state_entry, I still keep a "if wrong amount, refund the money" check in my money event. Better to be defensive than to expect things to work right all the time, especially when money is concerned. Related to the above again  Since you're not checking to see if permissions were actually granted, if you do decide to refund money, you'll have to make sure the permissions are available. And if they aren't, the best you can do is tell the customer (sorry, you paid the wrong amount, but the owner hasn't granted permissions, so I can't refund you anything). Or, throw in a run_time_permissions event, or use a timer or something, so you have some way of telling the owner "hey, you didn't grant these permissions, it won't work without debit permissions". In on_rez, you call llResetScript. That resets the script, which means the script starts running again in state_entry. What this means is, the block grab line never gets executd, because the script gets reset before it gets to that line. Again, the better thing to do would probably be to move that to state_entry as well. Edit: LOL, everyone beat me to it 
|
|
Sky Honey
Coder
Join date: 16 May 2005
Posts: 105
|
04-18-2006 12:07
From: Ziggy Puff Edit: LOL, everyone beat me to it  We need a real-time notification system that says "Warning! Three other people are responding to this post right now. Hurry up! 
|
|
Suzanna Soyinka
Slinky Slinky Slinky
Join date: 25 Nov 2005
Posts: 292
|
04-18-2006 12:18
Thank you everyone that took care of the issue. I didn't realize DetectedKey didn't work like that. Much appreciated. 
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
04-18-2006 12:27
the llDetected* functions only work in detect events (and functions called by detect events). detect events are the collisions, touches & sensor.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
|
04-18-2006 12:46
From: Ziggy Puff Related to the above again  Since you're not checking to see if permissions were actually granted, if you do decide to refund money, you'll have to make sure the permissions are available. And if they aren't, the best you can do is tell the customer (sorry, you paid the wrong amount, but the owner hasn't granted permissions, so I can't refund you anything). Or, throw in a run_time_permissions event, or use a timer or something, so you have some way of telling the owner "hey, you didn't grant these permissions, it won't work without debit permissions". ive been doing this since the feature came out for 2 reasons 1 its impossible to pay the wrong amount if your set pay price is correct. 2 some new ppl get freaked out when i give them a script that asks them for access to their money Ive not had any troubles with it... unlike permissions where a blip in the sim can remove them and 6 months later im getting yelled at becuase the dumb machine wouldnt give someone 5 bucks in change... ive had that happen numerous times before the feature i understand being defensive, but there is a point of getting so over defensive that it doesnt make since anymore, make a test machine without permissions or refunds and set it up with a correct pay price, get everyone you know and everyone they know to hammer the machine, it will never come up
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
04-18-2006 13:15
Well, the Wiki has some discussions of weirdness with child prims, changing states, and money events. It seems that in some cases, you could have a script that's in a state that has no money event, but the UI will still show the Pay option, and a user will still be able to pay the object. That money, of course, goes to the owner, but the script never gets notified. So explicitly paying the wrong amount isn't the only thing that can go wrong, there are other things that can go wrong as well, and have, at least in the past. The recommended solution is to have a money event in every state in your script, and pay the person back if the money isn't expected. Which gets back to requiring debit permissions. From: someone 2 some new ppl get freaked out when i give them a script that asks them for access to their money That would be the only reason not to do it. Since most vendor scripts I've written have been for myself or my friends, I explain it to them. And they trust me so far, I guess  So this reason doesn't really apply to me. But it would for someone selling a vendor to the general public. From: someone i understand being defensive, but there is a point of getting so over defensive that it doesnt make since anymore Of course. Personally, when it comes to money, I tend to be very very defensive. But, like you said, there's a price to pay for that. Obviously, every scripter decides this for themselves - where to draw the line. Anyway... I hear you, and I agree with what you're saying in general terms. I'm just very paranoid when it comes to money, so I tend to be extremely cautious. Like you said, the chance of something going wrong is probably close to zero, but I prefer to be sure 
|
|
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
|
04-18-2006 13:24
From: Ziggy Puff Well, the Wiki has some discussions of weirdness with child prims, changing states, and money events. It seems that in some cases, you could have a script that's in a state that has no money event, but the UI will still show the Pay option, and a user will still be able to pay the object. That money, of course, goes to the owner, but the script never gets notified.
So explicitly paying the wrong amount isn't the only thing that can go wrong, there are other things that can go wrong as well, and have, at least in the past. The recommended solution is to have a money event in every state in your script, and pay the person back if the money isn't expected. Which gets back to requiring debit permissions. maha! never thought of that becuase i usually go out of my way to make solid state scripts (but i love putting my self tru hell)
|
|
Sky Honey
Coder
Join date: 16 May 2005
Posts: 105
|
04-18-2006 13:35
From: Ziggy Puff Well, the Wiki has some discussions of weirdness with child prims, changing states, and money events. It seems that in some cases, you could have a script that's in a state that has no money event, but the UI will still show the Pay option, and a user will still be able to pay the object. That money, of course, goes to the owner, but the script never gets notified. Pay doesn't play well with linked prims, at least not the way I want it to. I have a multivendor of the type that shows either an icon view or a full size view. The icon view shows nine items and the full size view shows one. Touching goes back and forth between the views and you can Pay either the full size or the icon view. When they are not linked and whisper back and forth it works perfectly - you can Pay any of the ten prims and you get the right price and object. But if I link them, the Pay price is always the price set in the root prim (which is my full size view), even if the root prim is transparent or moved behind the icon view prims. So I have the hassle of 10 unlinked prims, which makes it hard to use and impossible to sell. 
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
04-18-2006 13:39
From: someone But if I link them, the Pay price is always the price set in the root prim (which is my full size view) Wow. Didn't know that. Thanks for the heads-up.
|
|
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
|
04-18-2006 13:44
yea its a royal pain in the butt with linked prims ... im currently testing how well setting them on the fly works but i havent any data yet
|
|
Sky Honey
Coder
Join date: 16 May 2005
Posts: 105
|
04-18-2006 14:48
From: Osgeld Barmy yea its a royal pain in the butt with linked prims ... im currently testing how well setting them on the fly works but i havent any data yet Please let us know if you find a way to make it work. My multivendor used alpha to hide each view, then I tried changing the width so one is hidden inside the other (which looks better because it doesn't flash so much in a laggy sim). I even tested with the root prim 2 meters off to the side but it still took the price from the root not the child I was clicking on. Doesn't seem as though that would be a hard bug to fix does it?
|
|
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
|
04-18-2006 15:18
i dunno about bug fixing, im not a programer, but it seems like they could use the system in place already for having mutiple sit targets in a linkset to set mutiple pay prices in linksets
|
|
Merlin Alphabeta
Registered User
Join date: 12 Feb 2006
Posts: 83
|
04-19-2006 06:54
From: sky Honey Pay doesn't play well with linked prims, at least not the way I want it to. I have a multivendor of the type that shows either an icon view or a full size view. The icon view shows nine items and the full size view shows one. Touching goes back and forth between the views and you can Pay either the full size or the icon view. When they are not linked and whisper back and forth it works perfectly - you can Pay any of the ten prims and you get the right price and object. But if I link them, the Pay price is always the price set in the root prim (which is my full size view), even if the root prim is transparent or moved behind the icon view prims. So I have the hassle of 10 unlinked prims, which makes it hard to use and impossible to sell.  lol excercise some creativity here - if you really want to do it the way you describe its certainly possible to do so (see point three below) three stylistic things I noticed in this thread: 1. screw custom starts - sometimes onrez fires, sometimes state_entry. I don't care. I just want to initialize my code. My template code file looks like: startup() { } default { on_rez(integer num) { startup(); } state_entry() { startup(); } } 2. debit perms got you down? Any script that'll error if not given the right permission, I use this function in the startup event: while(!(llGetPermissions() & PERMISSION_DEBIT)) { llRequestPermissions(llGetOwner(), PERMISSION_DEBIT); integer timeout = 60; while(!(llGetPermissions() & PERMISSION_DEBIT) && timeout > 0) { llSleep(1.0); timeout--; } } it doesn't spam the user with permission requests but waits until they've granted the right permission before initializing anything... 3. of course such a vendor would be saleable - it would be somewhat trivial to design it in such a way as to not require linked prims but still be boxable - think rezfoo on a small scale.
|
|
Xixao Dannunzio
Owner, X3D Enterprises
Join date: 20 Mar 2006
Posts: 114
|
07-12-2006 15:52
Not sure if you've solved this or not. I just skimmed the responses, looking for code: integer price = 300; string item = "Item Name Here"; string thank = "Thank you for shopping with us."; default { on_rez(integer total_number) { llResetScript(); } touch_start(integer num) { llSay(0, "To purchase "+item+", pay me L$"+(string)price+" (right-click > Pay)"); } state_entry() { llSetStatus(STATUS_BLOCK_GRAB, TRUE); llRequestPermissions(llGetOwner(), PERMISSION_DEBIT); llSetPayPrice(PAY_HIDE, [300, PAY_HIDE, PAY_HIDE, PAY_HIDE]); } money(key id, integer amount) { if(amount == price) { llSay(0, thank); llGiveInventory(id, item); } else if(amount > price) { integer refund = price - amount; llSay(0, "You have overpaid for this item. Your change is L$"+(string)refund+"."); llGiveMoney(id, refund); llGiveInventory(id, item); llSay(0, thank); } else if(amount < price) { llSay(0, "You have not paid enough for this item. Please pay L$"+price+" if you wish to purchase. Your money is being refunded."); llGiveMoney(id, amount); } } }
Also note that I'm not in-game to check this, but it should work fine.
|
|
Kyushu Tiger
Registered User
Join date: 12 Nov 2005
Posts: 92
|
12-24-2006 22:59
I have also been looking for a single item vendor using Fastpay. I tried Xixao's example, which worked with a couple of tweaks. First, the logic in the overpay calculation on line 28 is backwards: From: Xixao Dannunzio else if(amount > price) { integer refund = price - amount; llSay(0, "You have overpaid for this item. Your change is L$"+(string)refund+"."); llGiveMoney(id, refund); llGiveInventory(id, item); llSay(0, thank); }
That should be: integer refund = amount - price; It was giving a negative value. Also, the script did not compile for me at first because of a type mismatch on line 36: From: Xixao Dannunzio
{ llSay(0, "You have not paid enough for this item. Please pay L$"+price+" if you wish to purchase. Your money is being refunded."); llGiveMoney(id, amount); }
It worked when that was changed to: ... "You have not paid enough for this item. Please pay L$"+(string)price+" ... After that everything seems to work fine. I tested both the overpay and underpay scenarios by making the Fastpay amount higher and lower than the price. The one thing the script doesn't do is take any action if the debit permission is not granted. It asks for it, but if you say No it keeps chugging along like it's working. Not a problem if people are using the Fastpay, but if someone manages to trigger one of the refund conditions the refund will not work. Kyushu
|
|
Xixao Dannunzio
Owner, X3D Enterprises
Join date: 20 Mar 2006
Posts: 114
|
12-25-2006 12:40
Correct you are. This was written quite a while ago, and I had not logged in to test the code. Here is the corrected script: integer price = 300; string item = "Item Name Here"; string thank = "Thank you for shopping with us."; default { on_rez(integer total_number) { llResetScript(); } touch_start(integer num) { llSay(0, "To purchase "+item+", pay me L$"+(string)price+" (right-click > Pay)"); } state_entry() { llSetStatus(STATUS_BLOCK_GRAB, TRUE); llRequestPermissions(llGetOwner(), PERMISSION_DEBIT); llSetPayPrice(PAY_HIDE, [300, PAY_HIDE, PAY_HIDE, PAY_HIDE]); } money(key id, integer amount) { if(amount == price) { llSay(0, thank); llGiveInventory(id, item); } else if(amount > price) { integer refund = amount - price; llSay(0, "You have overpaid for this item. Your change is L$"+(string)refund+"."); llGiveMoney(id, refund); llGiveInventory(id, item); llSay(0, thank); } else if(amount < price) { llSay(0, "You have not paid enough for this item. Please pay L$"+(string)price+" if you wish to purchase. Your money is being refunded."); llGiveMoney(id, amount); } } }
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
Minor Suggestion
12-25-2006 13:40
The Money event can be factored to make it more efficient. money(key id, integer amount) { integer refund = amount - price; if(refund < 0) { llSay(0, "You have not paid enough for this item. Please pay L$"+(string)price+" if you wish to purchase. Your money is being refunded."); llGiveMoney(id, amount); } else { if(refund > 0) { llSay(0, "You have overpaid for this item. Your change is L$"+(string)refund+"."); llGiveMoney(id, refund); } llGiveInventory(id, item); llSay(0, thank); } }
|