/* ** Optimised, Newstyle, 08/12/93 */ #include "player.h" inherit "global/alias"; inherit "/global/nickname"; #define SOUL_OBJECT "/obj/handlers/soul" #undef SOUL_ERROR_CHECK static int time_left, *queue_depth, doing_it, last_command; static string *queued_commands, *in_command; static mixed *interupt; void create() { time_left = ROUND_TIME; queued_commands = in_command = ({ }); queue_depth = ({ 0 }); } void no_time_left() { time_left = -ROUND_TIME; } void soul_commands() { add_action( "nosoul", "nosoul", 1 ); add_action( "soul_com", "*", -1 ); add_action( "lower_check", "*", -10000 ); add_action( "drunk_check", "*", 10000 ); add_action( "soul_force_thingy", "SOUL_FORCE", 20000 ); alias_commands(); nickname_commands(); history_commands(); } int nosoul( string str ) { if( str == "on" ) this_object()->add_property( "nosoul", 1 ); else if( str == "off" ) this_object()->remove_property( "nosoul" ); else if( this_object()->query_property( "nosoul" ) ) this_object()->remove_property( "nosoul" ); else this_object()->add_property( "nosoul", 1 ); if( this_object()->query_property( "nosoul" ) ) write( "Soul turned off.\n" ); else write( "Soul turned on.\n" ); return 1; } #ifdef SOUL_ERROR_CHECK int soul_error_check() { if( !find_object( SOUL_OBJECT ) ) if( catch( call_other( SOUL_OBJECT, "??" ) ) ) { write( "Soul errors! Notify a wiz at once.\n" + "Use nosoul to turn the soul back on when it is fixed.\n" ); this_object()->add_property( "nosoul", 1 ); return 1; } return 0; } #endif int soul_force_thingy( string str ) { string str2; sscanf( str, "%s %s", str, str2 ); if( !this_object()->query_property( "nosoul" ) ) { #ifdef SOUL_ERROR_CHECK if( soul_error_check() ) return 0; #endif SOUL_OBJECT->soul_command( str, str2 ); } return 1; } int do_soul_force( string str ) { return command( "SOUL_FORCE " + str ); } int soul_com( string str ) { string str2; sscanf( str, "%s %s", str, str2 ); if( exec_alias( str, str2 ) ) return 2; if( !this_object()->query_property( "nosoul" ) ) { #ifdef SOUL_ERROR_CHECK if( soul_error_check() ) return 0; #endif if( SOUL_OBJECT->soul_command( str, str2 ) ) return 1; } return 0; } int soul_com_force( string str ) { if( file_name( previous_object() ) != SOUL_OBJECT ) return 0; command( str ); return 1; } void do_soul( string str, mixed bing ) { say( str, bing ); } int query_time_left() { return time_left; } int adjust_time_left( int i ) { return time_left += i; } void do_flush( int first ) { int i, *temp_qd; string com, *temp_ic; if( time_left < 0 || !sizeof( queued_commands ) ) return; if( !first ) { temp_ic = in_command; temp_qd = queue_depth; com = queued_commands[ 0 ]; /* Would delete be quicker here? */ queued_commands = queued_commands[ 1..1000 ]; queue_depth = ({ 0 }); in_command = ({ }); doing_it = 1; command( com ); doing_it = 0; in_command = temp_ic; queue_depth = temp_qd; return; } /* Does this \/ prevent more than 2 commands firing per round? */ for( i = 0; i < 2 && i < sizeof( queued_commands ); i++ ) call_out( "do_flush", 0, 0 ); call_out( "do_flush", 1, 1 ); } /* Called each heart_beat */ static void flush_queue() { if( time_left < 0 ) time_left += ROUND_TIME; else time_left = ROUND_TIME; remove_call_out( "do_flush" ); do_flush( 1 ); if( !sizeof( queued_commands ) ) { if( interupt && time_left > 0 ) { call_other( interupt[ 1 ], interupt[ 0 ], 0, interupt[ 2 ] ); interupt = 0; } doing_alias = ([ ]); in_alias_command = 0; in_command = ({ }); queue_depth = ({ 0 }); } } void set_interupt_command( string func, mixed ob, mixed arg ) { interupt = ({ func, ob, arg }); } int drunk_check( string str ) { last_command = time(); if( sizeof( in_command ) && in_command[ 0 ] == str ) return 0; if( this_object()->query_property( PASSED_OUT_PROP ) ) { if( str == "quit" ) return 0; write( "You have passed out, you cant do anything.\n" ); return 1; } if( str == "stop" || str == "restart" ) { queued_commands = ({ }); if( interupt && time_left < 0 ) call_other( interupt[ 1 ], interupt[ 0 ], -time_left, interupt[ 2 ] ); write( "Removed queue.\n" ); time_left = 0; return 0; } if( time_left < 0 || (!doing_it && sizeof( queued_commands )) ) { if( str[ 0..8 ] != "END_ALIAS" ) { str = replace( str, "@@", "@ @ " ); write( "Queued command " + str + ".\n" ); } if( str == "quit" ) { write( "If you are trying to quit and it is queueing things, use " + "'stop' to stop your commands, and or restart to start " + "your heartbeat.\n" ); } /* Is there not a nice insert function? */ queued_commands = queued_commands[ 0..queue_depth[ 0 ] - 1 ] + ({ str }) + queued_commands[ queue_depth[ 0 ]..255 ]; queue_depth[ 0 ]++; return 1; } if( interupt ) { call_other( interupt[ 1 ], interupt[ 0 ], 0, interupt[ 2 ] ); interupt = 0; } time_left -= DEFAULT_TIME; str = replace( str, "@@", "@ @ " ); add_history( str ); in_command = ({ str }) +in_command; if( !sizeof( queue_depth ) ) queue_depth = ({ 0, 0 }); else queue_depth = ({ queue_depth[ 0 ] }) +queue_depth; command( str ); in_command = in_command[ 1..1000 ]; queue_depth[ 1 ] = queue_depth[ 0 ]; queue_depth = queue_depth[ 1..1000 ]; if( interupt && time_left >= 0 ) { call_other( interupt[ 1 ], interupt[ 0 ], 0, interupt[ 2 ] ); interupt = 0; } return 1; } int lower_check( string str ) { time_left += DEFAULT_TIME; return( str == "stop" ); }