/** * A faller room. Used for such varied acts as falling, jumping, diving, and * other such activities over long distances. * @author Windy October 2001 */ #define PERCENT_DAMAGE 1 #define NUMERICAL_DAMAGE 2 inherit ROOM_OBJ; private string *begmess; private string apexmess; private string *endmess; private string *dest; private string messin; private string messout; private int duration; private int damage_amount; private int damage_type; void print_beginning( int which ); void print_apex(); void print_end( int which ); void add_beg_message( mixed arr ); void set_apex_message( string str ); void add_end_message( mixed arr ); void set_duration( int i ); int * query_damage(); void set_damage( int type, int amount ); void handle_landing(); /** @ignore yes */ void create() { begmess = ({ }); apexmess = ""; endmess = ({ }); dest = ({ }); messin = TP -> the_short() +" falls in from above."; messout = TP -> the_short() +" suddenly disappears."; damage_amount = 0; damage_type = 0; duration = 3; ::create(); } /** * Adds a message to the list of beginning messages. * @param arr either an array of messages or an individual one */ void add_start_message( mixed arr ) { if( pointerp( arr ) ) foreach( string str in arr ) add_start_message( str ); if( stringp( arr ) ) begmess += ({ arr }); } /** * Return an array containing all of the beginning messages. * @return an array of beginning messages */ string *query_start_messages() { return begmess; } /** * Set the apex message of the fall. * @param str the apex message */ void set_apex_message( string str ) { apexmess = str; } /** * Get the apex message for the fall. * @return the apex message */ string query_apex_message() { return apexmess; } /** @ignore yes */ string query_name() { return "falling from a high place"; } /** * Adds a message to the array of end messages. * @param arr either an array of messages or a single message */ void add_end_message( mixed arr ) { if( pointerp( arr ) ) foreach( string str in arr ) add_end_message( str ); if( stringp( arr ) ) endmess += ({ arr }); } /** * Sets the destination room(s). Upon landing, a room will be randomly selected * from this list. If more than one player is using the faller and there are * multiple destinations, each player has the possibility of landing in a * different room. * @param my_dest either a destination filename or an array of filenames */ void add_destination( mixed my_dest ) { if( pointerp( my_dest ) ) foreach( string str in my_dest ) add_destination( str ); else if( file_size( my_dest+".c" ) > 0 ) dest = uniq_array( dest + ({ my_dest }) ); dest -= ({ "/room/void" }); } /** * Returns the filename of a random dest room. * Note that this is not necessarily the destination that will be chosen upon * landing, it's just a random dest chosen from the list. * @return the destination room's filename */ object query_fall_destination() { string d; if( !sizeof( dest ) ) return 0; d = choice( dest ); return load_object( d ); } /* query_fall_destination() */ /** * Sets the message that everyone in the destination room receives when * someone 'falls in' from the faller * @param str the message to be sent */ void set_messin( string str ) { messin = str; } /** * Sets the message that everyone in the original room receives when someone * enters the faller room. * @param str the message to be sent */ void set_messout( string str ) { messout = str; } /** * Returns the messin message * @return the messin message */ string query_messin() { return messin; } /** * Returns the messout message. * @return the messout message */ string query_messout() { return messout; } /** * Sets the duration between messages. For example, a duration of '4' means that * there will be a four second delay between each message. You can control the * length of the fall this way. * @param i The number of seconds between each message */ void set_duration( int i ) { duration = i; } /** * Returns the number of seconds between fall messages * @return the number of seconds between messages */ int query_duration() { return duration; } /** * Returns the type and amount of damage (if any) done to the player as a result * of the fall. * @return an integer array. The first element is the damage type, the second * element is the amount. */ int *query_damage() { return ({ damage_type, damage_amount }); } /** * Sets the damage type and amount to be dealt on the fall. * @param type the type of damage. use 1 for an actual number * (i.e. do 100 damage to the player no matter what), or use 2 to do * a percentage of the player's max health to them. * @param amount the amount of damage */ void set_damage( int type, int amount ) { damage_type = type; if( amount < 0 ) damage_amount = -amount; else damage_amount = amount; } /** @ignore yes */ void print_beginning( int which ) { if( !sizeof( begmess ) ) return; tell_room( TO, begmess[which] ); if( which < sizeof( begmess ) - 1 ) call_out( "print_beginning", duration, which + 1 ); else call_out( "print_apex", duration ); } /** @ignore yes */ void print_apex() { if( apexmess != "" ) tell_room( TO, apexmess ); call_out( "print_end", duration, 0 ); } /** @ignore yes */ void print_end( int which ) { if( !sizeof( endmess ) ) return; tell_room( TO, endmess[which] ); if( which < sizeof( endmess ) - 1 ) call_out( "print_end", duration, which + 1 ); else handle_landing(); } /** @ignore yes */ void event_enter( object player, int notused, object notusedeither ) { if( living( player ) ) call_out( "print_beginning", 3, 0 ); } /** @ignore yes */ void handle_landing() { object d, *tmp, *obs; int i; if( !d = query_fall_destination() ) { tell_room( TO, "There are no destinations. Please notify a creator.\n"); d = find_object("/room/void"); } foreach( object ob in INV( TO ) ) { if( !living( ob ) ) continue; ob -> add_property("death_message", query_name() ); if( damage_type == PERCENT_DAMAGE ) i = ( ob -> query_max_hp() ) * ( damage_amount / 100.0 ) + 1; else i = damage_amount; if( ( ob -> query_hp() ) - i <= 0 ) ob -> do_death( TO ); else ob -> adjust_hp( - i, TO ); ob -> remove_property("death_message"); ob -> move_with_look( d, messin, messout ); if( i > 0 ) tell_object( ob, "Ouch! That hurt!\n"); } obs = INV( TO ); tmp = filter( obs, (: !living($1) :) ); tmp -> move( d ); obs -= tmp; if( !sizeof( INV( TO ) ) ) dest_me(); }