/*
* inventory.c
*
* Handle that every objects should have an inventory and environment
*
* (C) Frank Schmidt, Jesus@NorseMUD
*
*/
private static object env, *inv;
/* return environment */
nomask object __query_environment() {
return env;
}
/* return inventory */
nomask object *__query_inventory() {
if (arrayp(inv)) {
/* clean up */
inv -= ({ 0 });
return copy(inv);
}
return ({ });
}
#ifdef MUDOS_INVENTORY_INDEX
/* return inventory by index*/
nomask object __query_inventory_index(int i) {
if (arrayp(inv)) {
int sz;
/* clean up */
inv -= ({ 0 });
if ((sz=::sizeof(inv)) && i < sz)
return inv[i];
}
return 0;
}
#endif
/* return deep-inventory */
nomask object *__query_deep_inventory() {
if (arrayp(inv)) {
/* clean up */
int i;
object *di;
di = (inv -= ({ 0 }));
/* return our + nested inventory */
for (i=::sizeof(inv); --i >= 0; )
catch(di += call_other(inv[i], "__query_deep_inventory"));
return di;
}
return ({ });
}
/* return environment of an object */
static varargs object environment(object ob) {
if (!ob) return env;
return ob->__query_environment();
}
/* return inventory of an object */
static varargs object *all_inventory(object ob) {
if (!ob) return __query_inventory();
return ob->__query_inventory();
}
#ifdef MUDOS_INVENTORY_INDEX
/* return element in inventory according to index i */
static varargs object inventory_index(object ob, int i) {
if (!ob) return __query_inventory_index(i);
return ob->__query_inventory_index(i);
}
#endif
/* return deep-inventory of an object */
static varargs object *deep_inventory(object ob) {
if (!ob) return __query_deep_inventory();
return ob->__query_deep_inventory();
}
/* delete <ob> from inventory (used by move-func) */
nomask void __del_inventory(object ob) {
/* don't allow anything but move to call this */
if (AUTO_PRIV()) {
if (arrayp(inv)) {
/* clean up array */
if (!::sizeof(inv -= ({ ob })))
inv = 0;
}
}
}
/* add <ob> to inventory (used by move-func) */
nomask void __add_inventory(object ob) {
/* don't allow anything but move to call this */
if (AUTO_PRIV()) {
if (arrayp(inv))
inv += ({ ob });
else
inv = ({ ob });
}
}
/* move this object to a destination */
varargs int __MOVE_DEF(object dest) {
object oldply;
object *envs;
int i;
if (!dest)
/* ob->move() moved it to current object */
dest = previous_object();
if (dest) {
if (dest == this_object()) {
/* fy fy! */
error("Can't move object inside itself");
return 1;
}
/* moving to an object inside us? */
if (member_array(dest, __query_deep_inventory()) != -1) {
/* we solve it by "dropping" our stuff */
for (i=::sizeof(inv); --i >= 0; )
catch(call_other(inv[i], __MOVE_FUNC, env));
}
}
else
error("Bad argument 1 to move()");
/* delete us from old environment */
if (env) {
env->__del_inventory(this_object());
}
/* assign us to new environment */
env = dest;
/* add us to new environment */
if (env) {
env->__add_inventory(this_object());
}
#ifdef MUDOS_LIVING
/* check for livings and if we should call init() */
envs = all_inventory(env);
oldply=this_player();
if (living(this_object())) {
/* call init in destination */
GLOBAL->set_this_player(this_object());
/* call init in environment() and objects in environment() */
catch(call_other(env, __INIT_FUNC));
for (i=::sizeof(envs); --i >= 0; )
catch(call_other(envs[i], __INIT_FUNC));
}
/* call init in this_object() from all livings at destination */
map_array(filter_array(envs, "isliving", GLOBAL),
"do_init", GLOBAL, oldply);
/* reset correct this_player() (removing priv. level) */
GLOBAL->set_this_player(oldply);
#endif
/* move succeded */
return 0;
}
#ifdef MUDOS_MOVE_OBJECT
/* efun move_object, a bit more liberal than move() */
static varargs int move_object(mixed file, mixed dest) {
object ob;
mixed ret;
if (!dest) {
/* one arg only */
dest = file;
ob = this_object();
}
else {
if (stringp(file)) {
if (!(ob=find_object(file)))
ob = compile_object(file);
}
else
ob = file;
}
if (stringp(dest)) {
if (!(dest=find_object(file=dest)))
dest = compile_object(file);
}
if (ob) {
/* perform the move */
catch(ret=call_other(ob, __MOVE_FUNC, dest));
return ret;
}
return 0;
}
#endif