Skip to content

General Gift Giver (Limit of One Per Person)

This script allows you to give a gift to a customer (or visitor), but the customer is only allowed to receive the gift once.

If you are giving away really nice gifts, particularly “no copy” type gifts, you may want to limit it to one gift per customer.  This script allows you to do that.

The avatar receiving the gift does not have to be a member of a group.  If you would like require that the avatar be a member of your group, and also limit them to one gift, see this script.

When a customer receives the gift, the script remembers their key.  Then, if they try to obtain the gift a second time, a friendly note reminds them that there’s a limit of one gift per customer.

This script also does something else that other gift giver scripts don’t do:  it will keep track of how many gifts have been given out.

I have adapted a script that was written by Void Singer (, who has made a number of generous contributions to the Second Life community.  I added the gift giving portion of it, but it’s Void’s work that keeps a list of avatars who have already received gifts.

Place this script into an object.  The object, in this case, will be a poster with information on your gift – and for simplicity sake, I’ll call this the “gift poster object.”

The gift, itself, should be box.  You can make it look nice by using a wrapping paper texture and adding a ribbon and bow.  In the contents of the gift box, place the items that you are giving the customer, along with your landmark, of course.  Place the gift box in the contents of gift object poster.

You’ll find directions in the code below, if you’d like to give the customer a notecard along with the gift box

Be sure to copy everything between the two lines.  Script follows . . .


//GENERAL GIFT GIVER - Restricts One Gift to Each Customer
//Chimera Firecaster ( 05/2010
//Updated: VER 1.1 //Added ability to count number of gifts given away
//  Gives a gift to an avatar.  Once the avatar is given the gift, their key is saved
//  If the same avatar tries to obtain the gift a second time, he or she is gently told
//  that there's a limit of one gift per person
//  This also keeps track of the number of gifts given away.  If the owner of the
//  object in which this script has been placed clicks on it, a message appears
//  with information on how many gifts have been distributed.

//Note that with the script, the avatar does NOT have to be a member of group
//  Another version of this script is available which gives gifts to only to group members

//Much of this script is based on work by Void Singer
//  [ ]
//  And much of the credit should go to Void.  The primary source
//  of the code is his v7-D Advanced Avatar Greeter v1.4.1 Annotated
//  (C)2009 (CC-BY) [ ]    
//  Void Singer [ ]
//  All usages must contain a plain text copy of all foregoing comments

//Note: this is a FREE script.  It is given generously to the Second Life
//   community without the expectation of anything in return. It may be
//   distributed, but please do not charge for it.  That's bad form.  Besides, if
//   you dishonor the kindness of others, it will most certainly bring you bad karma.

//There is one place where you might want to insert your own text.  Look for
//  INSERT YOUR TEXT HERE.  Be sure to stay between the quote marks (").
/*//-- NOTE:
 Remove Any Instances Of "(gLstAvs = []) + " Or "(gLstTms = []) + " When Compiling This
 Script To MONO. They Are Provided For LSO Memory Preservation And Do Nothing In MONO
list    gLstAvs;        /*//-- List Of Avatars Keys Greeted --//*/
list    vLstChk;        /*//-- List Of Single Av Key Checked During Sensor Processing --//*/
integer vIdxLst;        /*//-- Index Of Checked Item In List (reused) --//*/
integer gIntMax = 500;  /*//-- Maximum Number of Names To Store --//*/
integer nGifts= 0;    //--Number of gifts given
 /*//-- Previous Code Line PreSet to Ease Removing Dynamic Memory Limitation Code --//*/
 /*//-- Next Code Line  Belongs to Dynamic Memory Limitation Section --//*/
integer int_MEM = 1000; /*//-- memory to preserve for safety (Needs to be > ~700)--//*/
 /*//-- Start Av Culling Section --//*/
integer gIntPrd = 172800; /*//-- Number Of Seconds After Detection To Store Av --//*/
integer vIntNow;          /*//-- Integer To Store Current Time During Sensor Processing --//*/
list    gLstTms;          /*//-- List Of Most Recent Times Avs Were Greeted At --//*/
list    vLstTmt;          /*//-- List To Store Timeout During Sensor Processing --//*/
 /*//-- End Av Culling Section --//*/
 on_rez(integer start_param){
 llResetScript();  //Re-sets the script each time the object is rezzed
 }                      //this will re-set nGifts (# of gifts given)

 /*//-- Next Code Line Belongs To Dynamic Memory Limitation Section --//*/
 gIntMax = int_MEM;                   /*//-- Override Max if Dynamic Memory Limitation is in use --//*/
 nGifts = 0;
 touch_start(integer total_number){
 if ( llDetectedKey(0) == llGetOwner() ) {//if the owner has touched
 llOwnerSay("Number of gifts disseminated: "+(string)nGifts); //say how many gifts given away
 /*//-- Save Current Timer to Now, Then Add Period and Save To Timeout--//*/
 vLstTmt = (list)(gIntPrd + (vIntNow = llGetUnixTime()));
 /*//-- Previous Code Line Belongs to Av Culling Section --//*/        
 /*//-- Is This Av Already In Our List? --//*/
 if (~(vIdxLst = llListFindList( gLstAvs, (vLstChk = (list)llDetectedKey( 0 )) ))){
 /*//-- Delete The Old Entries & Add New Entries to Preserve Order --//*/
 gLstAvs = llDeleteSubList( (gLstAvs = []) + gLstAvs, vIdxLst, vIdxLst ) + vLstChk;
 /*//-- Next Code Line Belongs to Av Culling Section --//*/
 gLstTms = llDeleteSubList( (gLstTms = []) + gLstTms, vIdxLst, vIdxLst ) + vLstTmt;

 llInstantMessage( (string)vLstChk, "Hi " + llDetectedName( 0) +". Unfortunately, there's a limit of one gift package per person." );
 /*//-- This is the 1st time for this Av! Add Them To The Lists & Preserve Max List Size--//*/            
 integer number = 0;

 llInstantMessage( (string)vLstChk, "Hi " + llDetectedName( 0 )+".  Here's your gift package!  Thanks for stopping by the store." );

 llGiveInventory(llDetectedKey(number), llGetInventoryName(INVENTORY_OBJECT,0));


 gLstAvs = llList2List( (gLstAvs = []) + vLstChk + gLstAvs, 0, gIntMax );
 /*//-- Next Code Line Belongs to Av Culling Section --//*/
 gLstTms = llList2List( (gLstTms = []) + vLstTmt + gLstTms, 0, gIntMax );
 /*//-- Start Dynamic Memory Limitation Section --//*/
 /*//-- Only lower Max List Size Once For Saftey --//*/
 if (int_MEM == gIntMax){
 /*//-- do we have plenty of room in the script? --//*/
 if (int_MEM > llGetFreeMemory()){
 /*//-- running out of room, set the Max list size lower --//*/
 gIntMax = ~([] != gLstAvs);
 /*//-- End Dynamic Memory Limitation Section --//*/
 /*//-- Start Av Culling Section --//*/
 /*//-- do we have keys? --//*/
 if (vIdxLst = llGetListLength( gLstTms )){
 /*//-- Do Any Need Culled? --//*/
 if (vIntNow > llList2Integer( gLstTms, --vIdxLst )){
 /*//-- Find The Last Index that hasn't hit timeout status --//*/
 @TheirBones; if (--vIdxLst) if (vIntNow > llList2Integer( gLstTms, vIdxLst )) jump TheirBones;
 /*//-- Thin the herd --//*/
 gLstAvs = llList2List( (gLstAvs = []) + gLstAvs, 0, vIdxLst );
 gLstTms = llList2List( (gLstTms = []) + gLstTms, 0, vIdxLst );
 /*//-- End Av Culling Section --//*/


%d bloggers like this: