This is more or less a drop in replacement for /lib/props/inventory.c. It has slightly different behavior- see the comments. Ignore the PERSISTENT ifdef stuff that is from some persistence code I have been working on and testing.
/*
Silenus - 2008/09/09
a replacement for /lib/props/inventory.c
It is slightly different from the DS version the main changes
are with the arguments accepted in the SetInventory mapping.
The following pairs are valid-
<file> : <int>
<file : <function>
<file> : <mapping>
The first case is the same as the current common case behavior
where the environment is checked for n items of base_name(<file>)
and items are cloned until the number equals <int> again.
The second case is almost the same as the first but <function>
is evaluated to determine the quantity.
The last case allows for some advance options to be set an includes
the first two as special cases. The format of the mapping is-
([ "pre" : <function>, // pre-check return 1 if you want the object
// to load and 0 if not
"post" : <function>, // function which allows you to customize the
// objects behavior after it has been moved into
// the environment
"quantity" : <function>|<int> // same as for case 1 and 2
"mobile" : <boolean> // determine if mobile tracking should be turned
// on. This changes the constraint from "quantity"
// objects in the room to "quantity" objects
// loaded by the room which are still extant
// since the room was last updated
*/
#ifdef PERSISTENT
#include <daemons.h>
int isLoaded();
#endif
private mapping Loaded = ([]);
private static mapping Inventory = ([]);
static void eventLoadInventory();
static void eventLoadItem(string file, mixed args, int count);
mapping GetInventory()
{
return copy(Inventory);
}
static void eventLoadItems(string file, mapping args)
{
int n;
object o;
Loaded[file] = Loaded[file] - ({0});
n = evaluate(args["quantity"]) - (args["mobile"] ? sizeof(Loaded[file]) :
sizeof( filter( Loaded[file], (: environment($1) == $(this_object()) :) ) ) );
for(int i = 0; i < n; ++i)
{
if( file->GetUnique() && sizeof( filter( findobs(file), (: environment($1) :) ) ) )
return;
if( evaluate(args["pre"],n-i) )
{
catch( o = new(file) );
if(o)
{
Loaded[file] += ({o});
o->eventMove( this_object() );
evaluate(args["post"],this_object(), n-i);
}
}
}
}
static void eventLoadInventory()
{
foreach(string file, mixed args in Inventory)
{
eventLoadItems(file,args);
}
}
mapping SetInventory(mapping m)
{
string error;
foreach(string k, mixed v in m)
{
if( k[<2..] == ".c" )
k = k[0..<3];
if( k[0..0] != "/" )
k = "/" + k;
if( intp(v) || functionp(v) ) v = ([ "pre" : (: 1 :), "post" : (: 0 :), "quantity" : v, "mobile" : 0 ]);
Inventory[k] = v;
Loaded[k] = ({});
}
/*
error = validate_mapping
(
({
([
"pre" : "function",
"post" : "function",
"quantity" : (: (!functionp(v) || !intp(v) || v <= 0) ? "Value either not a function, not an integer, or less than 1." : 1 :),
"mobile" : (: ((intp($1) && (v == 0 || v == 1)) ? 1 : "Value either 0 or 1") :)
])
}),
m
);
if( stringp(error) ) error( error );
*/
#ifdef PERSISTENT
if( !PERSIST_D->isLoading( this_object() ) && !isLoaded() )
#endif
eventLoadInventory();
return copy(Inventory);
}
varargs void reset()
{
eventLoadInventory();
}