/** * * This object handles all the inventory listing for rooms, when long() is * called. * It should convert like this: ({ /w/terano/womble#1234, /std/object#1324, * /global/creator#2523 }) into "Lady Midnite is standing here.\nA key and a * womble are floating happily.\n" * * @author Lynscar * @change Deutha * Added in support for the one_short, the_short stuff. Also added * in the 'last' stuff I think. * @change Pinkfish * Added in support for positions. * @change Terano * Rewrote removing all the foreachs, and getting rid of chicken and last * variables. Should be much nicer now. */ #include <position.h> // Comment me out to use the old process_non_living() code. #define NEW_PROCESS_NON_LIVING 1 mixed *process_living( object *int_livings ); string process_non_living( object *int_non_livings, int start ); void set_ignore_livings_in_inventory( int ignore ); int ignore_livings_in_inventory(); private nosave int _ignore_livings = 1; //It was decreed this be so. /** @ignore yes */ int env_check(object ob) { return environment(ob) == this_object(); } /** @ignore yes */ int living_check(object ob) { return living(ob); } /** @ignore yes */ mixed there_check(object ob) { return ob->query_property("there"); } /** * This method returns a string contents of description of the container. * NB: this_player() is _not_ included in the array if (s)he is present. * The ignore_living flag tells us if we should process living * objects as different or not. If we do not process them as * different (as you do in room descriptions), then this flag should * be 0. This is so that living objects can be kept an an * inventory of a player without stuff it up. ie: Pets. * @param start the start message before the contents * @param things the things to give the message for * @param ignore_living treat livings differently * @return a string contents description */ varargs string query_contents( string start, object *things, int ignore_living) { object *livings = ({ }), *non_livings = ({ }); mixed *bits; string return_string = ""; int groups; //Sort into living and non-living if( undefinedp( ignore_living ) ) ignore_living = ignore_livings_in_inventory(); if ( stringp( start ) ) return_string = start; if ( !arrayp( things ) ) { things = this_object()->find_inv_match( "", this_player() ); things -= ({ this_player() }); things = filter_array( things, "env_check", this_object()); } if ( !sizeof( things ) ) return ""; if (!ignore_living) { livings = filter(things, "living_check", this_object()); non_livings = things - livings; } else non_livings = things; //Process the livings if ( sizeof( livings ) ) { bits = process_living( livings ); return_string += bits[ 0 ]; groups = bits[1]; } //Process the non-livings if ( sizeof( non_livings ) ) { return_string += process_non_living( non_livings, groups ); } //Return the built string - Yay! if(return_string == "") return return_string; else return return_string = this_player()->colour_event("inventory", "") + return_string[0..<2] + "%^RESET%^\n"; } /** * @ignore * Internally process living objects and return a string. */ mixed *process_living( object *int_livings ) { int i; mapping positions = ([ ]); object live_temp; string my_pos, int_ret_string = "", *all_positions, current_pos, ministring; foreach( live_temp in int_livings ) { if ( undefinedp( my_pos = live_temp->query_position_short() ) ) my_pos = POSITION_DEFAULT; if ( undefinedp( positions[ my_pos ] ) ) positions[ my_pos ] = ({ live_temp }); else positions[ my_pos ] += ({ live_temp }); } //Sort into positions //For each position, build a ministring and add it all_positions = keys( positions ); i = 0; foreach( current_pos in all_positions ) { if(i==0) { ministring = "$C$$M$"; } else { ministring = "$M$"; } foreach( live_temp in positions[ current_pos ] ) { if ( !live_temp->query_visible( this_player() ) ) { continue; } ministring += live_temp->a_short(); } /* If more than one living */ if (!positions[current_pos][0]->query_position_dont_use_is_are()) { if ( sizeof( positions[ current_pos ] ) > 1 || positions[ current_pos ][0]->group_object() ) { if ( positions[ current_pos ][0]->query_position_multiple() ) { ministring += "$M$ are each " + current_pos; } else { ministring += "$M$ are " + current_pos; } } else { ministring += "$M$ is " + current_pos; } } else { ministring += "$M$ " + current_pos; } switch( current_pos ) { case SITTING: case STANDING: case KNEELING: case SWIMMING: case LYING: case MEDITATING: case CROUCHING: ministring += " here"; default: i++; if(i<sizeof(all_positions)-1) ministring += ", "; else if(i<sizeof(all_positions)) ministring += " and "; else ministring += ".\n"; int_ret_string += ministring; continue; } } return ({ int_ret_string, sizeof( all_positions ) }) ; } /** * @ignore */ string process_non_living( object *non_livings, int start ) { mapping positions; string position; object *items, item, *bulk; string here; string *room_items; int i; if(!sizeof(non_livings)) return ""; here = this_object()->query_property( "here" ); if (!here) return query_multiple_short( non_livings ) + ".\n"; positions = unique_mapping( non_livings, "there_check", this_object()); if ( positions[ 0 ] ) { positions[ here ] = positions[ 0 ]; map_delete( positions, 0 ); } i = start; room_items = ({ }); foreach( position, items in positions ) { bulk = ({ }); foreach( item in items ) { if( ( ( item->query_continuous() || item->query_collective() ) && item->query_how_many() > 1 ) || item->query_are_override() ) { // How do we make sure this all gets arranged properly...? if( item->query_short() == item->query_plural() ) room_items += ({ item->a_short() + " is " + position }); else room_items += ({ item->a_short() + " are " + position }); } else { bulk += ({ item }); } } if ( sizeof( bulk ) ) { room_items += ({ "$M$" + implode( bulk->a_short(), "" ) + "$M$ " + "$V$" + i + "=is,are$V$ " + position }); } i++; } return "$C$" + query_multiple_short( room_items ) + ".\n"; } /** * This method prints out the contents of the object matching. * @param word the string to match */ void list_contents( string words ) { write( query_contents( words ) ); } /** * @ignore */ int query_last() { log_file( "CUTELAST", "(%s) %s called query_last.\n", ctime( time() ), file_name( this_object() ) ); return 0; } /** * @ignore */ void adjust_last( int wibble ) { log_file( "CUTELAST", "(%s) %s called adjust_last.\n", ctime( time() ), file_name( this_object() ) ); return; } /** * Sets the ignore_living flag. Default is 1. * @param 1 to ignore livings, 0 not to * @see query_contents * @see ignore_livings_in_inventory **/ void set_ignore_livings_in_inventory( int ignore ) { _ignore_livings = !!ignore; } /* set_ignore_livings_in_inventory() */ /** * Returns the ignore_living flag. If livings are ignored, they are * displayed the same way as non-livings, ie: by short alone. If they are * not ignored, livings are displayed on a separate line and show their * positions. NB: passing a value to the 'ignore_livings' parameter of * query_contents overrides the ignore_living flag. * * @return 1 if livings are ignored, 0 if not. * @see set_ignore_livings_in_inventory * @see query_contents **/ int ignore_livings_in_inventory() { return _ignore_livings; }