/** * @main * This room is a craft shop which handles potions and salves. * Do not forget important things like set_save_dir() and * set_theft_handler(). * @index potion_shop * @started Thu Oct 29 1998 * @author Gruper * @see help::craft_shop */ #define CONVERT "/global/events"->convert_message #define MIN_VOLUME 1000 inherit "/std/shops/craft_shop_category"; /* Function prototypes */ void shopkeeper_say( string message ); int is_potion_or_salve( object ob ); void set_message_function( function wossname ); /* This is the function that handles messages to the player. */ private nosave function _message_function; /* If shopkeeper is set, the messages from message_function * will come from the shopkeeper. */ private nosave string _shopkeeper; /** * @ignore */ void create() { set_message_function( (: shopkeeper_say :) ); ::create(); set_allowed_to_sell( (: is_potion_or_salve :) ); } /** * This method sets the message function for the shop. * The message function can be useful to handle messages to * the player via the shopkeeper. The function should be of * type string -> void. If message_function is not set, we * default to a rather nice function. If message_function * is explicitly set to 0, no message will be given apart from * the standard messages from craft_shop. It is called from * is_potion_or_salve() and can also be used in do_buy() etc. * @param wossname A pointer to the function * @example set_message_function( (: nudity_say :) ), * where nudity_say looks like void nudity_say( string message ). * When using */ void set_message_function( function wossname ) { _message_function = wossname; } /** * @return Pointer to the message function */ function query_message_function() { return _message_function; } /** * This method sets the <b> name </b> of the shopkeeper that * the shop will look for when giving messages to the player. * @param name A name that identifies the shopkeeper to find_match */ void set_shopkeeper( string name ) { _shopkeeper = name; } /** * @return The name of the shopkeeper */ string query_shopkeeper() { return _shopkeeper; } /** * This is the default message function. * If the shopkeeper is in the shop, they will try to say message. */ void shopkeeper_say( string message ) { object *frog; /* the shopkeeper */ if( !message || message == "" ) message = "Tuppence a bucket, well stamped down!"; if( _shopkeeper ) { frog = match_objects_for_existence( _shopkeeper, this_object() ); if( sizeof( frog ) == 1 ) { frog[0]->init_command( "' "+ message ); /* Ok, we managed to give the message through the shopkeeper, * so we'll just bugger off. */ return; } } /* We couldn't find a shopkeeper, so we just write the message. * Boring, if you ask me. */ write( message ); return; } /** * This is the default function for checking if something can * be sold in a potion shop. If you override this, there is no * reason to inherit this file, so you can't. It will accept any * object that contains something which has an eat effect or an * apply effect. * @param ob The object that someone is trying to sell to the shop * @return success 1 if the object can be sold, 0 if not */ int is_potion_or_salve( object ob ) { object thing, *contents; int found_something; // Impure stuff! string contents_string; if( !ob->query_volume() ) { tell_creator( this_player(), "ob has 0 volume.\n" ); if( _message_function ) evaluate( _message_function, CONVERT( "There's nothing in "+ ob->the_short() +" that " "can be described as either potion or salve, "+ this_player()->the_short() +".\n" ) ); return 0; } else if( ob->query_volume() < MIN_VOLUME || ob->query_volume() < ( 7 * ob->query_max_volume() / 10 ) ) { tell_creator( this_player(), "ob does not contain enough stuff.\n" ); if( _message_function ) evaluate( _message_function, CONVERT( "We don't deal in quantities smaller than a cup, "+ this_player()->the_short() +".\n" ) ); return 0; } contents = all_inventory( ob ); if( !sizeof( contents ) ) { tell_creator( this_player(), "No contents.\n" ); if( _message_function ) evaluate( _message_function, CONVERT( ob->the_short() +" is empty, "+ this_player()->the_short() +"!\n" ) ); return 0; } foreach( thing in contents ) if( !( sizeof( thing->query_apply_effects() ) + sizeof( thing->query_eat_effects() ) ) ) { found_something = 1; // Impure } else { tell_creator( this_player(), "thing %s, effect %O.\n", thing->query_short(), thing->query_eat_effects() ); } contents_string = ( sizeof( contents ) > 1 ) ? query_multiple_short( contents, "the" ) +" are neither potions nor " "salves, or they are " : contents[0]->the_short() +" is neither potion nor salve, or it is "; // Found impure stuff if( found_something ) { if( _message_function ) evaluate( _message_function, CONVERT( "Either "+ contents_string +"impure, or so weak as " "to make no difference, "+ this_player()->the_short() +"." ) ); return 0; } return 1; }