// This file is part of the TMI mudlib distribution. // Please include this header if you use this code. // Written by Buddha@TMI, modularized and revised (5/1/92) // This is a common module to the different standard objects available. // Also thanks to Mobydick for his work here. // #define DEBUG #include <mudlib.h> #include <uid.h> #include <move.h> // prototypes mixed query(string what); varargs void set(string what, mixed value, int access_level); int remove(); int move(mixed dest); void add(string what, mixed arg); varargs void delete(string what, mixed arg); // The id parsing stuff. int id(string str) { int i; string *parts, *ids; ids = query("id"); if (!pointerp(ids) || !ids) return 0; if(!stringp(str)) return 0; // bad input if(member_array(str, ids) != -1) return 1; // match! } // The argument 'dest' is either a string or an object. // The return values are given in move.h // updated to use standard properties 8/14/92 buddha@tmi // also thanks to truilkan for his "last_location" idea, which I converted. // some stuff commented out by buddha 9/7/92 for speed int move(mixed dest) { object ob; string err; int bulk, mass; bulk = query("bulk"); mass = query("mass") ; // this 'attached' check added by Truilkan 92/06/02 // if (environment(this_object()) && this_object()->query("attached")) // return MOVE_NOT_ALLOWED; if (stringp(dest)) { ob = find_object(dest); if (!ob) { dest = resolv_path("cwd", dest); err = catch(call_other(dest, "???")); if (err) { write(err + "\n"); return MOVE_NO_DEST; } ob = find_object(dest); } } else ob = dest; if(environment() && !environment()->release_object(this_object())) return MOVE_NOT_ALLOWED; if (!ob || !ob->receive_object(this_object())) return MOVE_NOT_ALLOWED; if (living(this_object()) && living(ob) && !((int)ob->move_ok())) return MOVE_NOT_ALLOWED; if (environment(this_object()) == ob) return MOVE_NOT_ALLOWED; if (ob->query("volume") < (int)query("bulk")) return MOVE_NO_ROOM; if (ob->query("capacity") < (int)query("mass")) return MOVE_TOO_HEAVY ; if (environment()) { environment()->add("volume", bulk); environment()->add("capacity", mass) ; } set("last_location", environment()); move_object(ob); ob->add("volume", -bulk); ob->add("capacity", -mass) ; return MOVE_OK; } /* * To destruct objects, call 'remove()' in the object. The default here * is to allow destruction and update encumbrance. * All objects inside this object is also moved to the "outside" (if any). */ int remove() { object super; int i, res ; object *ob_list; super = environment(this_object()); if (super) { super->add("volume", query("bulk")); super->add("capacity", query("mass")) ; ob_list = all_inventory(this_object()); for (i=0; i < sizeof(ob_list); i++) { res = ob_list[i]->move(super); if (res!=MOVE_OK) { write ("An object vanishes. Tell a wiz!\n") ; } } } destruct(this_object()); return 1; } // clean_up() is called on all objects by the driver in an attempt to do some // garbage collection. If it returns 0, then it will never be called again, // otherwise it will be called after an interval set in the runtime config // file. int clean_up(int inherited) { object env, *contents; int i; if (inherited) return 0; if (userp(this_object())) return 0; /* don't clean_up players */ env = environment(); if (env && userp(env)) return 1; /* carried ob */ if (env && environment(env)) return (int)environment(env)->clean_up(); /* recurse */ contents = deep_inventory(this_object()); if (contents) { for (i=0;i<sizeof(contents);i++) if (userp(contents[i])) return 1; /* holding a user */ } if (!env) { /* Don't clean up base objects from /std/ */ if (!inherits(ROOM, this_object()) && !clonep(this_object()) && (file_name(this_object())[0..4] == "/std/")) return 0; /* we're a room with no users inside or a lost object */ remove(); return 1; } return 1; /* try again later... */ } // anything can get anything right now. int receive_object(object foo) { return 1; } // anything can be moved from it right now. int release_object(object foo) { return 1; } // The recursive light checking function. // Blame Mobydick, it's his fault. int check_light() { int i ; object *obs ; // First, if this object is emitting light, we have a light source. if (query("light")) return 1 ; // Second, if this object has no inventory, we do not have a light source. obs = all_inventory(this_object()) ; if (!obs) return 0 ; // Third, if this object is opaque, we do not have a light source. if (query("opaque")) return 0 ; // If this is a transparent container that is not itself emitting light, then // we recursively check light on its contents until we find one of them that // is emitting light or we run out, in which case we do not have a source. for (i=0;i<sizeof(obs);i++) { if (obs[i]->check_light()) return 1 ; } return 0 ; }