/** * This handler keeps track of things buried in rooms. * Loosely based on Pinkfish's burial effect. * @author Sandoz, 2002. * @changed Added recycling of objects - Sandoz, 09/09/2002. */ #define BURY_TIMEOUT 300 // 5 min. #define NO_BURY "DNB_ME" private mapping burial_containers; private object *recycled; private int call_id, hits, misses; private void expire_buried(); void create() { burial_containers = ([ ]); recycled = ({ }); } /* create() */ /** * This method buries an object in a room. * @param room the room burying the object * @param ob the object to bury */ void bury_object( object room, object ob ) { if( room && ob ) { object cont; if( !cont = burial_containers[room] ) { if( sizeof( recycled -= ({ 0 }) ) ) { burial_containers[room] = cont = recycled[0]; recycled = recycled[1..]; hits++; } else { cont = clone_object("/std/container"); cont->add_property("burial object", 1 ); burial_containers[room] = cont; misses++; } } ob->move( cont ); ob->add_property( NO_BURY, 1, BURY_TIMEOUT - 1 ); if( !call_id ) call_id = call_out( (: expire_buried :), BURY_TIMEOUT ); } } /* bury_object() */ /** * This method is called by the room object when it is dested. * It will get rid of the buried objects. */ void room_dested() { object room, cont; room = PO; if( room && ( cont = burial_containers[room] ) ) { INV(cont)->move("/room/rubbish"); if( !sizeof(INV(cont)) ) recycled += ({ cont }); else cont->dest_me(); map_delete( burial_containers, room ); } if( !sizeof(burial_containers) ) { remove_call_out(call_id); call_id = 0; } } /* room_dested() */ /** * This method is called by the recover command after * a successful recover to do some maintenance stuff. * @param room the room recover was used in */ void event_recover( object room ) { object cont; if( room && ( cont = burial_containers[room] ) && !sizeof( INV(cont) ) ) { recycled += ({ cont }); map_delete( burial_containers, room ); } } /* event_recover() */ /** @ignore */ mapping query_burial_containers() { return burial_containers; } /** @ignore */ private void expire_buried() { object room, cont, *obs; call_id = 0; foreach( room, cont in burial_containers ) { if( !cont ) { map_delete( burial_containers, room ); continue; } if( !room ) { INV(cont)->move("/room/rubbish"); if( !sizeof(INV(cont)) ) recycled += ({ cont }); else cont->dest_me(); map_delete( burial_containers, room ); continue; } obs = filter( INV(cont), (: !$1->query_property(NO_BURY) :) ); if( sizeof( obs ) ) obs->move("/room/rubbish"); if( !sizeof( obs = INV(cont) ) ) { recycled += ({ cont }); map_delete( burial_containers, room ); } } if( sizeof(burial_containers) ) call_id = call_out( (: expire_buried :), BURY_TIMEOUT ); } /* expire_buried() */ /** * This method returns all the stuff buried in the specified room. * @param room the room to get the burial objects from * @return the array of buried objects */ object* query_buried_objects( object room ) { if( room && burial_containers[room] ) return INV( burial_containers[room] ); return ({ }); } /* query_buried_objects() */ /** * This method returns the container for a specific room, * that has all the buried items in it. * @param room the room to get the burial object for * @return the container with the buried items */ object query_buried_container( object room ) { return burial_containers[room]; } /* query_buried_container() */ /** @ignore yes */ void dest_me() { object cont; foreach( cont in values(burial_containers) ) { if( cont ) { INV(cont)->move("/room/rubbish"); cont->dest_me(); } } } /* dest_me() */ /** @ignore yes */ mixed stats() { return ({ ({"burial containers", sizeof(burial_containers) }), ({"recycled containers", sizeof(recycled) }), ({"recycle hits", hits }), ({"recycle misses", misses }), }); } /* stats() */