/** * This is a small inheritable to allow places to do engraving. Put a * piece of code in the init function which calls the engrave_init() * function. * @example * inherit "/std/room/basic_room"; * inherit "/std/shops/engrave"; * * void init() { * basic_room::init(); * engrave_init(); * } /\* init() *\/ * @author Macchirton * @see set_engraving_language() * @see query_engraving_language() * @see set_style(); * @see query_style() * @see set_letter_cost() * @see query_letter_cost() * @see set_engrave_shopkeeper() * @see query_engrave_shopkeeper() * @change 17th of May 1998 Pinkfish * Turned into an inheritable base and reworked to make it work with * add_command correctly. * @changed 21/03/01 Shiannar - Fixed bizzare behaviour of engrave_objects(). * @changed 23/09/02 Sandoz - Made the shopkeeper code and a few more things work. */ #define ENGRAVE_PROP "engraveable" private int letter_cost, use_shop_keeper; private object shop_keeper; private string language, style; void create() { TO->add_help_file("engrave"); letter_cost = 200; style = "neat engraved letters"; language = "common"; } /* create() */ /** * This method sets the language messages will be engraved in. * The default language is common. * @param str the language to engrave in * @see query_engraving_language() */ void set_engraving_language( string str ) { if( !LANGUAGE_H->query_language_written(str) ) error("The language "+str+" is not a valid written language.\n"); language = str; } /* set_engraving_language() */ /** * This method returns the language messages are engraved in. * @return the language messages are engraved in * @see set_engraving_language() */ string query_engraving_language() { return language; } /** * This method sets the writing style for engravings. * The default is "neat engraved letters". * @param str the string to set as the style of the engravings * @see query_style() */ void set_style( string str ) { style = str; } /** * This method returns the style messages will be engraved in. * @return the style we engrave in * @see set_style(); */ string query_style() { return style; } /** * This method sets the cost of engraving one letter. * @param i the cost to set * @see query_letter_cost() */ void set_letter_cost( int i ) { letter_cost = i; } /** * This method returns the cost of engraving 1 letter. * @return the cost of engraving 1 letter * @see set_letter_cost() */ int query_letter_cost() { return letter_cost; } /** * Sets the shop keeper for the engraving shop. If the shop keeper is * not set then it will not be checked for. If it is checked it will be * checked for the existance of. Make sure to check for the shopkeeper's * existance each reset, and clone him when needed. * @param ob the shop keeper to test for * @see query_engrave_shopkeeper() */ void set_engrave_shopkeeper( object ob ) { use_shop_keeper = 1; shop_keeper = ob; } /* set_engrave_shopkeeper() */ /** * This method returns the currently ste shop keeper for the engraving shop. * @return the shop keeper * @see set_engrave_shopkeeper() */ object query_engrave_shopkeeper() { return shop_keeper; } /** * This method is called when a living object is attempted to be engraved. * This should be overridden in the inheritable to print out the * message you wish to say. If this function returns 1 then the * default failed message is not used. * @param liv the living objects * @return 0 use default fail mesasage, 1 override default fail message * @see do_engrave() */ protected int engrave_living( object *obs ) { return 0; } /* engrave_living() */ /** * This method is called if the objects in question are unable to be * engraved. * This should be overridden in the inheritable to print out the * message you wish to say. If this function returns 1 then the * default failed message is not used. * @param obs the objects which could not be engraved. * @return 0 use default fail mesasage, 1 override default fail message * @see do_engrave() */ protected int engrave_wrong_items( object *obs ) { return 0; } /* engrave_wrong_items() */ /** * This method is called if the player does not have enough money to * complete the engraving. * This should be overridden in the inheritable to print out the * message you wish to say. If this function returns 1 then the * default failed message is not used. * @param obs the objects which were unable to be engraved * @param cost the cost of the objects to be engraved * @return 0 use default fail mesasage, 1 override default fail message * @see do_engrave() */ protected int engrave_no_money( object *obs, int cost ) { return 0; } /* engrave_no_money() */ /** * This method is called when the engrave is successful. * This should be overridden in the inheritable to print out the * message you wish to say. If this function returns 1 then the * default success message is not used. * @see do_engrave() */ protected int engrave_objects( object *obs, int cost ) { return 0; } /* engrave_objects() */ /** @ignore yes */ private int engravable_item( object ob ) { string type; type = ob->query_property("shop type"); return type == "jewellers" || type == "armoury" || ob->query_property(ENGRAVE_PROP) == 1; } /* engravable_item() */ /** * This method does the actual engraving. * @param things the things to get engraved. * @param message the message to engarve on the objects * @see engrave_init() */ protected int do_engrave( object *things, string message ) { int cost; string str, place; object *liv, *engravable; if( use_shop_keeper && ( !shop_keeper || ENV(shop_keeper) != TO ) ) { add_failed_mess("There is no-one here to engrave $I for you.\n", things ); return 0; } liv = filter( things, (: living($1) :) ); if( sizeof(liv) && !engrave_living(liv) ) { add_failed_mess("You cannot engrave messages on $I, because they are " "living things.\n", liv ); } if( !sizeof( things -= liv ) ) return 0; if( !sizeof( engravable = filter( things, (: engravable_item :) ) ) ) { if( !engrave_wrong_items( things ) ) add_failed_mess("You cannot engrave anything on $I.\n", things ); return 0; } place = TO->query_property("place") || "default"; str = implode( explode( message, " ") - ({ 0, ""}), ""); cost = strlen(str) * letter_cost * sizeof(engravable); if( TP->query_value_in( place ) < cost ) { if( !engrave_no_money( engravable, cost ) ) add_failed_mess("You don't have enough money to engrave $I, you " "need "+MONEY_H->money_value_string( cost, place )+".\n", engravable ); return 0; } TP->pay_money( MONEY_H->create_money_array( cost, place ), place ); engravable->add_read_mess( message, style, language ); add_succeeded_mess(""); if( !engrave_objects( engravable, cost ) ) add_succeeded_mess( ({"You engrave the message \""+message+"\" into " "$I for "+MONEY_H->money_value_string( cost, place )+".\n", "$N get$s $I engraved with a message.\n"}), engravable ); return 1; } /* do_engrave() */ /** * This method should be called in the inheriting room's init function. IUt * will setup the commands to allow the object to be engraved. * @see do_engrave() */ void init() { add_command("engrave", "<string> on <indirect:object:me>", (: do_engrave( $1, $4[0] ) :) ); } /* init() */ /** @ignore yes */ mixed stats() { return ({ ({"letter cost", letter_cost }), ({"using shopkeeper", use_shop_keeper }), ({"shopkeeper", shop_keeper }), ({"engraving language", language }), ({"engraving style", style }), }); } /* stats() */