Skip to content

Instantly share code, notes, and snippets.

@antonyfairport
Created February 7, 2012 10:27
Show Gist options
  • Save antonyfairport/1759017 to your computer and use it in GitHub Desktop.
Save antonyfairport/1759017 to your computer and use it in GitHub Desktop.
Script to give random objects from the content of a prim, with emphasis on the objects being no-copy
//////////////////////////////////////////////////////////////////////
// Z&A Give Random Object
// By Antony Fairport
//
// Simple example of how you could create a script that will give a
// random object from inventory, on touch, and also allow for the
// fact that some or all of the objects might be no-copy.
//
// Note that this approach probably won't scale so well if the object
// is filled with many items. In that case, rather that reloading
// the list each time, it'd probably make sense to do some in-script
// management of a once-loaded list.
//
// Also note that this script does "one copy only" tracking and this
// too places an upper-limit on how well the script scales. I would
// suggest compiling as Mono.
//
// Use in a live situation at your own risk.
//////////////////////////////////////////////////////////////////////
// Globals.
list g_lObjects = [];
list g_lGivenTo = [];
//////////////////////////////////////////////////////////////////////
// Default state.
default
{
//////////////////////////////////////////////////////////////////
// Jump to the load state on startup.
state_entry()
{
state LoadAvailable;
}
}
//////////////////////////////////////////////////////////////////////
// State that loads the available objects.
state LoadAvailable
{
//////////////////////////////////////////////////////////////////
// Load the list on state entry.
state_entry()
{
// Get how many objects are available.
integer iMax = llGetInventoryNumber( INVENTORY_OBJECT );
integer i;
// Make sure the list is empty.
g_lObjects = [];
// For each object in inventory...
for ( i = 0; i < iMax; i++ )
{
// Get the name of the item.
string sObject = llGetInventoryName( INVENTORY_OBJECT, i );
// If the current owner has transfer rights...
if ( ( llGetInventoryPermMask( sObject, MASK_OWNER ) & PERM_TRANSFER ) == PERM_TRANSFER )
{
// ...add the item to the applicable list.
g_lObjects += [ sObject ];
}
}
// If there's something to give...
if ( llGetListLength( g_lObjects ) > 0 )
{
// ...go the the giver state...
state GiveRandomObject;
}
else
{
// ...go to the empty state.
state RunningOnEmpty;
}
}
}
//////////////////////////////////////////////////////////////////////
// State where we wait to give a random object.
state GiveRandomObject
{
//////////////////////////////////////////////////////////////////
// Handle the end of a touch.
touch_end( integer num_detected )
{
// Note that we only give to the first toucher in this touch
// event. If more than one avatar touched at the same time the one
// that SL has decided was first "wins" this time around. The others
// will get their chance in a moment.
// Get who's after the object.
key kToucher = llDetectedKey( 0 );
// Have they already had something from us?
if ( ~llListFindList( g_lGivenTo, [ kToucher ] ) )
{
llSay( 0, "Sorry " + llDetectedName( 0 ) + ", you've already had an item from me." );
}
else
{
// Randomise the list...
list l = llListRandomize( g_lObjects, 1 );
// Give the object at the head of the list to the person who touched us.
llGiveInventory( kToucher, llList2String( l, 0 ) );
// Add that person to the list of people who've had something.
g_lGivenTo += [ kToucher ];
// If the object was no-copy/trans we'll have one less item in
// inventory. Refresh our list of what's available.
state LoadAvailable;
}
}
//////////////////////////////////////////////////////////////////
// Handle changes.
changed( integer change )
{
// If the content, or the owner, has changed...
if ( ( change & CHANGED_INVENTORY ) || ( change & CHANGED_OWNER ) )
{
// ...reset the script.
llResetScript();
}
}
}
//////////////////////////////////////////////////////////////////////
// State we go to when inventory is empty.
state RunningOnEmpty
{
//////////////////////////////////////////////////////////////////
// Handle the end of a touch.
touch_start( integer num_detected )
{
llSay( 0, "Sorry, I'm now empty." );
}
//////////////////////////////////////////////////////////////////
// Handle changes.
changed( integer change )
{
// If the content, or the owner, has changed...
if ( ( change & CHANGED_INVENTORY ) || ( change & CHANGED_OWNER ) )
{
// ...reset the script.
llResetScript();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment