One Item Per Avatar with Notecard

This script was tested and works on OpenSim version 0.7.4!

This variant requires you to have a notecard in the primitive's inventory containing avatar key x object name pairs. For example, the following configuration:

dbd87522-9078-4666-adf3-9b11caccba2da#Gravestone Dropper
1be55407-a792-476d-a5e3-19907f0a02bf#Toilet Dropper

will give the Gravestone Dropper object to the avatar with the key dbd87522-9078-4666-adf3-9b11caccba2da and the Toilet Dropper object to the avatar with the key 1be55407-a792-476d-a5e3-19907f0a02bf.

givernotecard.lsl
///////////////////////////////////////////////////////////////////////////
//  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.        //
///////////////////////////////////////////////////////////////////////////
 
key nQuery = NULL_KEY;
integer nLine = 0;
list nList = [];
//pragma inline
string nName = "Presents";
 
default
{
    state_entry()
    {
        llSetTimerEvent(1);
        if(llGetInventoryType(nName) != INVENTORY_NOTECARD) {
            llOwnerSay("Notecard " + nName + " not found in inventory.");
            return;
        }
        nQuery = llGetNotecardLine(nName, nLine);
    }
    touch_start(integer total_number)
    {
        key av = llDetectedKey(0);   
        integer i = llGetListLength(nList)-2;
        do {
            if(llList2Key(nList, i) != av) jump continue;
            llGiveInventory(av, llList2String(nList, i+1));
@continue;
            i -= 2;
        } while(i>-1);
    }
 
    dataserver(key id, string data) {
        if(id != nQuery) return;
        if(data == EOF) {
            list objects = [];
            integer i = llGetInventoryNumber(INVENTORY_OBJECT)-1;
            do {
                objects += llGetInventoryName(INVENTORY_OBJECT, i);
            } while(--i>-1);
            i=llGetListLength(nList)-2;
            do {
                if(llListFindList(objects, (list)llList2String(nList, i+1)) != -1) jump continue;
                llOwnerSay("At least one item was not found in the inventory, please check the notecard...");
                state stop;
@continue;
                i -= 2;
            } while(i > -1);
            llOwnerSay("Notecard read and checked, all is ok!");
            return;
        }
        if(data == "") jump next_line;
        nList += llParseString2List(data, ["#"], []);
@next_line;
        nQuery = llGetNotecardLine(nName, ++nLine);
    }
 
    changed(integer change) { if(change & CHANGED_INVENTORY) llResetScript(); }
 
    on_rez(integer param) { llResetScript(); }
}
 
state stop {
    touch_start(integer num) { llResetScript(); }
 
    changed(integer change) { if (change & CHANGED_INVENTORY) llResetScript(); }
 
    on_rez(integer num) { llResetScript(); }
}