// newbienag.lsl // Give an inventory object only to newbies // Written by Kex Godel on March 20, 2005 // Released under Creative Commons Attribution license // http://creativecommons.org/licenses/by/2.0/ // // This script gives an inventory item only if the person who collides with // the object is under a certian age. // // Features: // - Remembers who it already recently checked, so it does not bother looking // them up again // - Relays to other nearby objects with the same name running the same script // to let them know it has already checked this person and served them. // - Age checking code incorporates leap days until 2100 // - Timeout will resume work if dataserver doesn't respond // maximum newbie age to recieve item integer NEWBIE_DAYS = 14; // how long to wait for the dataserver before giving up integer DATASERVER_TIMEOUT = 30; // length of FIFO list of people to remember you already gave to. integer NAG_LIST_LENGTH = 25; // channel to communicate to other same objects to let them know you already gave. integer MULTI_CONTROL_CHANNEL = 861562; key gDataserveKey = NULL_KEY; integer gLastCollisionTime = 0; string gDetectedName; string gDetectedKey; list recentlyNagged; // Return number of days since 2000-01-01 integer datestamp(integer year, integer month, integer day){ year = year - 2000; list monthdays = [0,31,28,31,30,31,30,31,31,30,31,30,31]; integer i=1; integer sum = year * 365 + (year/4) + day; for(i=1;i<month;i++){ if( (i != 2) || (year % 4 != 0)){ sum+=llList2Integer(monthdays,i); }else { sum+=29; } } if(year % 4 == 0){ return sum - 1; } return sum; } // Convert the SL date string type (yyyy-mm-dd) to days since 2000-01-01 integer date2datestamp(string date){ integer year = (integer)date; integer month = (integer)llGetSubString(date,5,6); integer day = (integer)llGetSubString(date,8,9); return datestamp(year,month,day); } // Add someone to our short-term do-not-nag list addRecentlyNagged(string name){ if(!wasRecentlyNagged(name)){ recentlyNagged+=name; if(llGetListLength(recentlyNagged) > NAG_LIST_LENGTH){ recentlyNagged = llDeleteSubList(recentlyNagged,0,0); } } } // Check if someone is already on our do-not-nag list integer wasRecentlyNagged(string name){ if(llListFindList(recentlyNagged,[name]) > -1){ return TRUE; } return FALSE; } // Get someone's age in days based on the current date (PST) integer getAge(string timestr){ integer todayDate = date2datestamp(llGetTimestamp()); integer agentBirthDate = date2datestamp(timestr); return todayDate - agentBirthDate; } default{ state_entry(){ gDataserveKey = NULL_KEY; gLastCollisionTime = 0; llListen(MULTI_CONTROL_CHANNEL,llGetObjectName(),"",""); } listen(integer ch, string name, key id, string msg){ addRecentlyNagged(msg); } collision_start(integer cnt){ integer i; for(i=0;i<cnt;i++){ string name = llDetectedName(i); if(!wasRecentlyNagged(name)){ // check if already making a request, or if the request has timed out if(gDataserveKey == NULL_KEY || (gLastCollisionTime + DATASERVER_TIMEOUT < llGetTime())){ gDetectedName = name; gDetectedKey = llDetectedKey(0); addRecentlyNagged(name); llSay(MULTI_CONTROL_CHANNEL,gDetectedName); // pass the message on not to nag gDataserveKey = llRequestAgentData(gDetectedKey,DATA_BORN); } } } } dataserver(key req, string data){ if(req == gDataserveKey){ if(getAge(data) <= NEWBIE_DAYS){ llGiveInventory(gDetectedKey,"notecard"); }else{ // do nothing for oldbies } gDataserveKey = NULL_KEY; // clear so a new request can be made } } }