/** * This file contains all the code need to handle the types of carrying * which npcs tend to involve themselves in. * @author Pinkfish * @changed Changed query_wearing_hidden() to deal better with items * with multiple types - Sandoz, Dec. 2003. */ #include <money.h> object* query_wearing(); /** * This method returns the list of types of things which are passed into * the array. * <p> * Two elements in an array is returned, the first element is the list of * all of the different types which are worn and the second is the list * of types corresponding to each of the inputs. * @param things the things to check * @return a two element array * @see armour_list() */ protected varargs mixed query_types_worn( object *things ) { int i; string *types; mixed stuff; types = ({ }); if( !things ) things = (object *)TO->query_wearing(); i = sizeof( stuff = (mixed *)things->query_type() ); while( i-- ) { if( stringp( stuff[ i ] ) ) stuff[ i ] = ({ stuff[ i ] }); if( !pointerp( stuff[ i ] ) ) { printf("%O (%s) has an invalid type. Please bug report it.\n", things[ i ], (string)things[ i ]->query_short() ); stuff[ i ] = ({"broken"}); } types += stuff[ i ]; } return ({ types, stuff }); } /* query_types_worn() */ /** * This method returns the items that are hidden by something on top of * them. * @param looker the person looking at the items * @param things an optional set of things * @return the hidden worn types */ object* query_wearing_hidden( object looker, object *things ) { string *types, *under, under_type; object *worn, *ret; mixed obj_types; int i, j; worn = ( !things ? query_wearing() : things ); obj_types = query_types_worn( worn ); types = obj_types[0]; obj_types = obj_types[1]; ret = ({ }); i = sizeof(worn); while( i-- ) { if( worn[i]->query_visible(looker) ) { j = sizeof( obj_types[i] ); // We cycle through each type, and are only hidden if every // type is covered. This way jumpers won't cover whole dresses, // because the skirt part is still visible. - Sandoz, 2003. while( j-- ) { under = CLOTHING_H->query_clothing_hiding( obj_types[i][j] ); if( sizeof(under) ) { foreach( under_type in under ) { if( member_array( under_type, types ) != -1 ) obj_types[i] = delete( obj_types[i], j, 1 ); } } // No more visible types left. if( !sizeof( obj_types[i] ) ) { ret += ({ worn[i] }); break; } } } else { ret += ({ worn[i] }); } } return ret; } /* query_wearing_hidden() */ /** * This method returns a string list of the armours which the player * is wearing. It will show also modify the list to show only hidden * items (items under other items are considered hidden). * @param things the things to get the list of armours from * @param hidden_only only show the list of hidden objects * @see query_types_worn() * @see query_living_contents() */ protected string armour_list( object *things, int hidden_only, int self ) { object* hidden; hidden = query_wearing_hidden( TP, things ); if( hidden_only ) things = filter( hidden, (: $1->query_visible( TP ) :) ); else things = things - hidden; if( !sizeof( things ) ) return 0; // Order them in a reasonable way. if( !self ) things = sort_array( things, (: CLOTHING_H->query_clothing_depth($2->query_type()) - CLOTHING_H->query_clothing_depth($1->query_type()) :) ); return query_multiple_short( things ); } /* armour_list() */ /** * This method does the inventory of the living objects we all know and * love. It is used in the long description and the inventory commands. * @param self are we showing our own inventory * @see armour_list() * @index inventory */ string query_living_contents( int self ) { string s; string *limbs, *bits, *strs; object *carry, *conts, *holding, *arms; object money, ob; int i, coins, pos; mixed fish; s = ""; strs = ({ }); if( !limbs = TO->query_limbs() ) limbs = ( TO->query_race_ob() )->query_limbs(); conts = filter( INV(TO), (: $1->short(0) :) ); money = present( MONEY_ALIAS, TO ); i = sizeof( holding = (object *)TO->query_holding() + ({ }) ); if( !arms = (object *)TO->query_armours() - holding ) arms = ({ }); carry = conts - arms - holding - ({ money }); while( i-- ) { if( holding[i] ) { bits = ({ limbs[i] }); ob = holding[i]; holding[i] = 0; while( ( pos = member_array( ob, holding ) ) != -1 ) { bits += ({ limbs[pos] }); holding[pos] = 0; } strs += ({ ob->a_short()+" ("+ query_multiple_short( bits, "a", 1 )+")" }); } } if( sizeof(strs) ) s += "$I$+10,+0=%^RED%^Holding%^RESET%^ : "+ query_multiple_short( strs )+".\n$I$-10,-0="; if( sizeof( arms ) ) { if( fish = armour_list( arms, 0, self ) ) s += "$I$+10,+0=%^YELLOW%^Wearing%^RESET%^ : "+fish+ ".\n$I$-10,-0="; if( self && ( fish = armour_list( arms, 1, self ) ) ) s += "$I$+10,+0=%^YELLOW%^(under)%^RESET%^ : "+fish+ ".\n$I$-10,-0="; } if( sizeof( carry ) ) { if( fish = TO->query_contents( 0, carry, 1 ) ) { if( pointerp(fish) ) s += "$I$+10,+0=%^GREEN%^"+fish[1]+"%^RESET%^: "+ fish[0]+"$I$-10,-0="; else s += "$I$+10,+0=%^GREEN%^Carrying%^RESET%^: "+fish+ "$I$-10,-0="; } } if( self && s == "") s = "You are empty handed.\n"; if( self && !TO->check_dark( ENV(TO)->query_light() ) ) { s += "Your purse contains "+( money ? query_multiple_short( (string *)money->half_short( 1 ) ) : "only moths" )+".\n"; } else { if( money ) coins = (int)money->query_number_coins(); if( coins ) { s += ( self ? "Your" : CAP( (string)TO->HIS ) ) + " purse is "; switch( coins ) { case 0..10: s += "home to only moths!"; break; case 11..100: s += "tinkling with coins."; break; case 101..300: s += "bulging with coins."; break; default: s += "fit to burst!"; } s += "\n"; } } return s; } /* query_living_contents() */