Deposit Box
|
Dmitriy Gausman
Registered User
Join date: 16 May 2007
Posts: 132
|
10-16-2009 22:12
I am making a game and one of the challenges is to find 3 coins (simple flattened cylinder prims) on one part of the SIM, touch each coin whereby the rezzed coins dispense coins to the finder. The "next owner" permissions are transfer only. That part works fine. Then they do other challenges and one of the last ones it to go to a bank where there is a deposit box. The only way I could think of to get them to "deposit" the coins into the box is to go into inventory and do Ctrl-Drag onto the box. Then, as they deposit each coin, it gets sent to me so I can be sure the completed the task. None of this involves any money, just prims. What seems to be happening is a person can deposit 2 of the three coins. But when they attempt to deposit the third, there is a script error that says " Deposit Box: Missing inventory item ''. I would prefer not to have them touch the box but I think that's the only way for me to get their name without using a scanner. I know I am doing something wrong but not sure what. Here is the script I am using. Any hints would be appreciated. string depositor;
default { state_entry() { llSetText("Coin Drop \n Please touch to start", < 0.5, 0.0, 0.0 >, 1.0); llAllowInventoryDrop(TRUE); } touch_start(integer num) { depositor = ""'; llSetText("To place coins in the box \n Use ctrl + drag from inventory",<.5,0,0>,1.0); depositor = llDetectedName(0); }
changed(integer change) { if (change & (CHANGED_INVENTORY | CHANGED_ALLOWED_DROP)) { while (llGetInventoryNumber(INVENTORY_OBJECT) > 0) { llGiveInventory(llGetOwner(), llGetInventoryName(INVENTORY_OBJECT, 0)); //llRemoveInventory(llGetInventoryName(INVENTORY_OBJECT, 0)); }
} } state_exit() { llResetScript(); } }
|
Moon Corrigible
Registered User
Join date: 19 Jan 2007
Posts: 75
|
10-17-2009 09:09
I am NOT at all sure about this but I'm wondering if you need to take out the CHANGED_INVENTORY (which will trigger every time something is added or removed - thus will trigger when you remove the item as well as when they drop the coin in) and just keep the CHANGED_ALLOWED_DROP.
I've got to play with it inworld to have any shot of figuring it out - hehehe.
|
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
|
10-17-2009 09:10
Many people don't understand the business about using CTRL+drag+drop to move items from inventory to the contents of an object, so they get frustrated and give up. I have used a token system similar to yours and have used notecards as tokens instead of objects for that reason. You don't need to use CTRL to drag+drop a notecard. Also, people tend to drop spurious pseudotokens in drop boxes. They mess up your count and clutter the drop box. Consider scripting the drop box to accept only specific items that you made. Try something like this .. changed (integer change) { if(change & (CHANGED_INVENTORY|CHANGED_ALLOWED_DROP)) { if(llGetInventoryNumber(INVENTORY_NOTECARD)) { string cardName = llGetInventoryName(INVENTORY_NOTECARD,0); if(cardName == "SPECIAL_COIN" & llGetInventoryCreator(cardName) == llGetOwner()) { llGiveInventory(llGetOwner(), cardName); llInstantMessage(llGetOwner(), depositor + " just sent you a coin."); } } } }
As you are doing already, be sure that your token notecards are no-copy/no-mod/transfer so they can't be forged and so they don't remain in the dropbox once they are accepted and passed along to you. There's also no way that you will ever reach the llResetScript function, as written. The script will stay in state default because there's nowhere else to go, hence no state_exit event will fire. If you really want to reset the script to prepare for the next visitor, consider using a timer event to reset the script after, say, two minutes. Set the timer event in the touch_start event so it begins running when your visitor clicks the drop box. Finally, consider what might happen if visitor #2 comes up and clicks the box while visitor #1 is busy dropping tokens in it. You'll never know whose tokens are whose. So, put a test in the touch_start event, like this ... touch_start(integer num) { ++touchcount; // declare integer touchcount = 0 globally if (touchcount > 1) { return; } llSetText("To place coins in the box \n Drag them from inventory",<.5,0,0>,1.0); depositor = llDetectedName(0); llSetTimerEvent(120); // Or whatever time you think is reasonable }
ETA: Aha... Moon is probably right. When you give yourself the token in inventory, that will fire the changed event again. Do as Moon suggests and remove the CHANGED_INVENTORY mask and see what happens. CHANGED_INVENTORY is superfluous anyway, since the tokens are all no mod.
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask....  Look for my work in XStreetSL at 
|
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
|
10-17-2009 13:26
I got distracted in mid-thought and didn't finish tying up a couple of loose ends before I posted my suggestion earlier. The changed event I outlined will correctly send you only tokens that are legitimate (i.e., not forged or irrelevant). If someone DOES drop a bogus token in the box, though, it may mess up the system. You need a way to get rid of unwanted tokens ...... changed (integer change) { if(change & (CHANGED_ALLOWED_DROP)) { if(llGetInventoryNumber(INVENTORY_NOTECARD)) { string cardName = llGetInventoryName(INVENTORY_NOTECARD,0); if(cardName == "SPECIAL_COIN" & llGetInventoryCreator(cardName) == llGetOwner()) { llGiveInventory(llGetOwner(), cardName); llInstantMessage(llGetOwner(), depositor + " just sent you a coin."); } else { llRemoveInventory(INVENTORY_NOTECARD,0); } } } }
Someone could still drop non-notecard items in the box, but they're no problem, so ignore them. One other loose end occurs to me.... Depending on how you store and hand out tokens from your vendor, they may all have similar but non-identical names. If your store three copies of a token in the vendor's inventory, they will be named SPECIAL_COIN, SPECIAL_COIN1, and SPECIAL_COIN2. To avoid having the drop box reject 2/3 of the tokens, you can modify its script slightly by writing ... if( llGetSubString(cardName,0,11) == "SPECIAL_COIN" & llGetInventoryCreator(cardName) == llGetOwner())
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask....  Look for my work in XStreetSL at 
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
10-17-2009 20:43
the problem is, it won't really detect who's dropping the coins other than when they touch it. and also, changed inventory isn't triggered when the item is removed by a script, not sure if it's the same for giving a no copy item. all that said.
how about having the deposit box listen on some channel, and when they click the coin they find, it can announce the avatar's key on the channel using llRegionSay. the deposit box can keep track of which coins they found. when they have found them all, the deposit box can do it's thing to let you know or whatever
|
Indeterminate Schism
Registered User
Join date: 24 May 2008
Posts: 236
|
10-18-2009 07:20
A completely different approach, IF they can rez near the 'bank'. I suggest this because you say "I would prefer not to have them touch the box". Instead of dropping the coins into the bank, why not rez them near/on it, which most people have no problem with. Then just chat between objects. Something along these lines, although my daughter is hassling me and I haven't read your original code properly. In coin: default{ on_rez(integer StartParam){ llListen(-517, "Bank", NULL_KEY, "Ack"  ; llWhisper(-517, llKey2Name(llGetOwner())); llSetTimerEvent(5.0);} timer(){ llSetTimerEvent(0.0); llOwnerSay("Not near the bank, please pick me up and rez me closer"  ;} listen(integer ChannelIn, string FromName, key FromID, string Message){ llOwnerSay("Deposit acknowledged, well done"  ; llDie();} } In bank: default{ on_rez(integer StartParam){ llListen(-517, "Coin", NULL_KEY, ""  ;} listen(integer ChannelIn, string FromName, key FromID, string Message){ llInstantMessage(llGetOwner(), Message + " has deposited a coin in the bank."  ;} } ETA: Oops, Ruthven suggested something similar first. I plead distraction
|
Dmitriy Gausman
Registered User
Join date: 16 May 2007
Posts: 132
|
10-23-2009 00:29
Thank you to everyone who offered advice. I started to play with the idea of having the person "sit" on a linked object so the deposit box would recognize who was there and then press buttons for each coin, thus getting credit.
I am going to sift through all the suggestions and see which works best. I am not sure I want people to rezz the coins on the SIM though I like the idea about the listen and then let he coin die to "clean up" after itself. The more i think about it, maybe that is the way to go. I agree that the Ctrl-Drag is not going to be understood by many and if an item is already highlighted in their inventory, more things might get tossed in than planned.
If I come up with something decent, I will repost here should someone want to use it for something else.
|