/* Player object. By Fudge */ #include <channel.h> #include <type.h> inherit obj OBJECT; inherit con CONTAINER; inherit bod BODY; inherit M_MESSAGES; inherit "/std/editor"; inherit "/std/modules/m_autoload_string"; inherit "/std/modules/m_language"; static object user; /* This players user object */ static string input_to_func; /* The function we're redirecting input to */ static object input_to_obj; /* The object we're redirecting input to */ static object possessing; /* The object this player is possessing */ static int linkdead; /* Are we linkdead? */ static int quitting; /* Are we in the process of quitting? */ static int timestamp; /* Last time we got input */ static int more_line_num; /* How far in the file we're more'ing are we */ static string *more_lines; /* All the lines in the file we're more'ing */ string last_tell; /* Who did we get a tell from last? */ static mapping item_commands; /* Commands that are local to worn/wielded items. */ string real_name; /* This players real name */ string email_address; /* The email address */ mapping board_read; /* Status of messages read */ mapping environment_variables; /* The environment variables of the player */ string title; /* The title */ string player_name; /* The player name */ string password; /* The password */ string *cmd_path; /* The path which is searched for comands */ string *channels; /* Channels we're listening to */ mapping alias; /* The players aliases */ int last_login; /* The last login */ mapping guilds; /* The guilds the player is a member of. The values are the guild title. */ void save_me( void ); void restore_me( void ); void set_env( string name, mixed value ); mixed query_env( string name ); string query_title( void ); void create( void ) { obj::create(); con::create(); bod::create(); board_read = ([ ]); channels = ({ "gossip", "announce" }); title = "$N the nondescript"; long_desc = ""; set_brief( "A nondescript player" ); timestamp = time(); set_env( "cwd", "/" ); set_env( "pwd", "/" ); item_commands = ([ ]); } /* Save the player */ void save_me( void ) { save_object( "/data/players/"+player_name+".o" ); } /* Restore the player */ void restore_me( void ) { if( 0 == restore_object( "/data/players/"+player_name+".o" ) ) { write( "Error while restoring \"/data/players/" + player_name+".o" ); write( "Please notify the administration."); return; } if( board_read == 0 ) board_read = ([ ]); set_id( player_name ); if( alias == 0 ) alias = ([ ]); } /* Login the player */ void login_player( void ) { int i; string *didlog; /* If we're a wiz, show the didlog since last login */ if( SECURE_D->query_priv( player_name ) > 0 ) { didlog = DID_D->get_entries( last_login ); if( didlog != 0 ) { for( i = 0; i < sizeof( didlog ); i++ ) { if( didlog[i] == "" ) write( "\n" ); else write( didlog[i] ); } } } if( last_login == 0 ) { /* A new player */ EVENT_D->event( "new_player", player_name ); last_login = time(); } else { last_login = time(); /* Call the login event */ EVENT_D->event( "player_login", player_name ); } /* Gender less? Set the player to male */ if( query_gender() == 0 ) set_gender( 1 ); /* Set the proper name */ if( query_proper_name() == 0 ) { set_proper_name( capitalize( player_name ) ); } /* Set the current working directory */ if( query_env( "cwd" ) == 0 ) set_env( "cwd", "/" ); /* Subscribe to default channels */ if( channels == 0 ) { channels = ({ "gossip", "announce" }); } /* Register with the subscribed channels */ for( i = 0; i < sizeof( channels ); i++ ) { if( CHANNEL_D->query_channel( channels[i] ) != 0 ) { CHANNEL_D->chan_join( channels[i], this_player() ); } else { channels[i] = 0; } } initialize_race(); /* Load up this players race */ set_brief( query_title() ); /* Set the brief description */ set_hit_skill( "combat/unarmed" ); } int query_last_login( void ) { return( last_login ); } void set_last_tell( string who ) { last_tell = who; } string query_last_tell( void ) { return( last_tell ); } int is_living( void ) { return 1; } int is_player( void ) { return 1; } int is_possessing( void ) { if( possessing != 0 ) return 1; return 0; } object query_possessing( void ) { return( possessing ); } void set_possessing( object ob ) { possessing = ob; } void set_env( string name, mixed value ) { if( environment_variables == 0 ) { environment_variables = ([ ]); } environment_variables[name] = value; save_me(); } mixed query_env( string name ) { if( environment_variables == 0 ) { environment_variables = ([ ]); } return( environment_variables[name] ); } string *query_env_indices( void ) { if( environment_variables == 0 ) { environment_variables = ([ ]); } return( map_indices( environment_variables ) ); } int query_ansi( void ) { if( environment_variables == 0 ) { environment_variables = ([ ]); } return( query_env( "ansi" ) ); } void set_ansi( int state ) { set_env( "ansi", state ); save_me(); } int query_board_read( string board ) { return( board_read[ board ] ); } void set_board_read( string board, int num ) { board_read[ board ] = num; save_me(); } void set_user( object usr ) { user = usr; } void set_title( string t ) { title = t; set_brief( query_title() ); } string query_title( void ) { string t; t = title; if( t == 0 || t == "" ) t = "$N the title less"; return( replace_string( t, "$N", capitalize( player_name ) ) ); } string query_title_string( void ) { return( title ); } void set_linkdead( int flag ) { if( flag == 1 ) { set_brief( query_title() + " [link-dead]" ); linkdead = call_out( "do_quit", LINKDEAD_TIMEOUT ); } else { set_brief( query_title() ); if( linkdead != 0 ) remove_call_out( linkdead ); linkdead = 0; } } void set_editing( int flag ) { if( flag == 1 ) set_brief( query_title() + " [editing]" ); else set_brief( query_title() ); } int query_linkdead( void ) { return( linkdead > 0 ); } int query_idle( void ) { return( time() - timestamp ); } object query_user( void ) { return(user); } void set_name( string name ) { player_name = name; set_id( name ); } string query_name( void ) { return player_name; } string query_Name( void ) { return capitalize( player_name ); } void set_password( string passwd ) { password = passwd; } string query_password( void ) { return password; } void set_real_name( string str ) { real_name = str; } string query_real_name( void ) { return( real_name ); } void set_email_address( string str ) { email_address = str; } string query_email_address( void ) { return( email_address ); } void initialize_cmd_path( void ) { cmd_path = ({ "/cmds/player" }); } /* Add a path to the command path */ void add_cmd_path( string path ) { cmd_path -= ({ path }); cmd_path += ({ path }); } string *query_path( void ) { return cmd_path; } void add_channel( string chan ) { if( channels == 0 ) channels = ({ }); channels -= ({ chan }); channels += ({ chan }); } void remove_channel( string chan ) { if( channels == 0 ) channels = ({ }); channels -= ({ chan }); } string *query_channels( void ) { return( channels ); } /* Redirect input to another funtion */ void input_to( string func ) { input_to_obj = this_player(); input_to_func = func; } /* Redirect input to another object */ void input_to_object( object ob, string func ) { input_to_obj = ob; input_to_func = func; } /* Send a message to the player */ void message( string str ) { if( this_object()->is_snooped() ) this_object()->do_snoop( str ); this_object()->query_user()->wrap_message( str ); } /* Send an almost unmodified message to the player */ void message_orig( string str ) { if( this_player()->is_snooped() ) this_player()->do_snoop( str ); query_user()->put_message( str ); } void write_prompt() { string prompt; if( this_player()->is_editing() ) { out( "%^GREEN%^edit> %^RESET%^" ); return; } prompt = query_env( "prompt" ); if( prompt == 0 ) { prompt = "> "; } else { prompt = replace_string( prompt, "%n", capitalize( player_name ) ); prompt = replace_string( prompt, "%m", MUD_NAME ); prompt = replace_string( prompt, "%w", query_env( "cwd" ) ); prompt = replace_string( prompt, "%_", "\n" ); prompt = replace_string( prompt, "%l", this_environment()->file_name() ); if( this_environment()->query_area() == 0 ) { prompt = replace_string( prompt, "%a", "(none)" ); } else { prompt = replace_string( prompt, "%a", this_environment()->query_area() ); } prompt = replace_string( prompt, "%h", "" + query_stat( "hp" ) ); prompt = replace_string( prompt, "%H", "" + query_stat( "max_hp" ) ); } out( prompt + "%^RESET%^ " ); } /* More a set of lines */ void more( string *lines ) { string msg; int height; height = query_env( "height" ); if( height == 0 ) height = 23; more_line_num = 0; more_lines = lines; if( sizeof( lines ) > height + more_line_num ) { out_unmod( implode( lines[more_line_num..more_line_num+height], "\n" ) ); out( "\n%^BOLD%^--More--(" + ((more_line_num+height)*100)/sizeof( lines ) + "%)%^RESET%^" ); more_line_num += height + 1; input_to( "more_prompt" ); } else { msg = implode( lines[more_line_num..], "\n" ); out_unmod( msg + "\n" ); } } /* Write out the more prompt after each page */ void more_prompt( string arg ) { string msg; int height; if( arg == "" ) arg = " "; switch( arg[0] ) { case 'q': case 'Q': write_prompt(); return; break; } height = query_env( "height" ); if( height == 0 ) height = 23; if( sizeof( more_lines ) > height + more_line_num ) { out_unmod( implode( more_lines[more_line_num..more_line_num+height], "\n" ) ); out( "\n%^BOLD%^--More--(" + ((more_line_num+height)*100)/sizeof( more_lines ) + "%)%^RESET%^" ); more_line_num += height + 1; input_to( "more_prompt" ); } else { msg = implode( more_lines[more_line_num..], "\n" ); out_unmod( msg + "\n" ); write_prompt(); } } /* Look around */ void do_look( int brief ) { this_environment()->event( "body_look", this_player() ); write( " " ); if( query_env( "show_location" ) ) write( "%^BOLD%^" + query_environment()->file_name() + "%^RESET%^" ); write( this_environment()->query_desc() ); } /* Move */ void do_go( string dir ) { string error; error = this_environment()->body_exit( this_player(), dir ); if( error != 0 ) write( error ); } /* Quit */ void do_quit( string str ) { object *objs; int i; this_object()->compose_autoload_string(); objs = query_inventory(); if( is_possessing() ) call_other( "/cmds/wiz/possess", "main", "" ); for( i=0; i < sizeof( objs ); i++ ) { if( objs[i]->is_undroppable() ) { objs[i]->destruct(); } else if( objs[i]->move( this_object()->query_environment() ) ) { this_object()->targetted_action( "$N $vdrop $o.", 0, objs[i] ); } else { objs[i]->destruct(); } } this_object()->simple_action( "$N $vquit." ); for( i = 0; i < sizeof( channels ); i++ ) { if( CHANNEL_D->query_channel( channels[i] ) != 0 ) { CHANNEL_D->chan_leave( channels[i], this_object() ); } else { channels[i] = 0; } } EVENT_D->event( "player_logout", player_name ); quitting = 1; query_user()->quit(); } /* Destruct this player */ void destruct( void ) { object *objs; int i; objs = query_inventory(); for( i=0; i < sizeof( objs ); i++ ) { if( objs[i]->move( this_object()->query_environment() ) ) { objs[i]->destruct(); } } if( query_environment() != 0 ) query_environment()->remove_object( this_object() ); destruct_object( this_object() ); } /* Alias handling */ int is_alias( string cmd ) { if( alias == 0 ) alias = ([ ]); if( alias[cmd] != 0 ) return( 1 ); return( 0 ); } string query_alias( string cmd ) { if( alias == 0 ) alias = ([ ]); return( alias[cmd] ); } void add_alias( string cmd, string new_alias ) { if( alias == 0 ) alias = ([ ]); alias[cmd] = new_alias; } void remove_alias( string cmd ) { if( alias == 0 ) alias = ([ ]); alias[cmd] = 0; } mapping query_aliases( void ) { if( alias == 0 ) alias = ([ ]); return( alias ); } /* Add to the item command mapping */ void add_item_command( string command, object ob ) { if( item_commands == 0 ) item_commands = ([ ]); item_commands[command] = ob; } void remove_item_command( string command ) { if( item_commands == 0 ) item_commands = ([ ]); item_commands[command] = 0; } /* Guild routines */ void join_guild( string guild ) { if( guilds == 0 ) guilds = ([ ]); guilds[guild] = GUILD_D->query_guild_title( guild ); cmd_path += ({ "/cmds/guild/" + guild }); save_me(); } void leave_guild( string guild ) { if( guilds == 0 ) guilds = ([ ]); guilds[guild] = 0; cmd_path -= ({ "/cmds/guild/" + guild }); set_title( "$N the guildless" ); save_me(); } int guild_member( string guild ) { if( guilds == 0 ) guilds = ([ ]); if( guilds[guild] != 0 ) return( 1 ); return( 0 ); } string *query_guilds( void ) { return( map_indices( guilds ) ); } /* Process input from the player */ void receive_message( string message ) { mixed result; string func; string cmd; string arg; string *exits; int i; int flag; flag = 0; /* Update the timestamp so we're not idle */ timestamp = time(); arg = ""; if( this_player()->is_snooped() ) this_player()->do_snoop( message ); /* Redirect the input somewhere else */ if( input_to_func != "" ) { func = input_to_func; input_to_func = ""; call_other( input_to_obj, func, message ); /* Are we editing? */ } else if( is_editing() ) { this_player()->edit( message ); } else { /* Expand the command */ message = ALIAS_D->expand_alias( message ); /* Split the input into command and argument */ if( sscanf( message, "%s %s", cmd, arg ) != 2 ) cmd = message; if( is_alias( cmd ) ) { message = ALIAS_D->do_expand( query_alias( cmd ), arg ); if( sscanf( message, "%s %s", cmd, arg ) != 2 ) cmd = message; } if( cmd != "" ) { if( cmd[0] == '\'' ) { if( arg == "" ) { arg = cmd[1..]; } else { arg = cmd[1..] + " " + arg; } cmd = "say"; } else if( cmd[0] == ';' ) { if( arg == "" ) { arg = cmd[1..]; } else { arg = cmd[1..] + " " + arg; } cmd = "emote"; } } /* Substitute 'me' with my name */ if( arg == "me" ) arg = this_player()->query_id(); /* Check for a command, and call the command if it's found */ if( !flag ) { for( i = 0; i < sizeof( cmd_path ); i++ ) { if( file_exists( cmd_path[i] + "/" + cmd + ".c" ) ) { call_other( cmd_path[i] + "/" + cmd, "main", arg ); flag = 1; break; } } } /* Check for a verb */ if( !flag ) { result = PARSE_D->parse( cmd + " " + arg ); if( result != 0 ) { if( typeof( result ) == T_STRING ) { write( result ); } flag = 1; } } if( !flag ) { /* Check for an item command */ int i; string *item_cmds; item_cmds = map_indices( item_commands ); for( i = 0; i < sizeof( item_cmds ); i++ ) { if( item_cmds[i] == cmd ) { call_other( item_commands[ item_cmds[i] ], "do_" + cmd, arg ); flag = 1; } } } if( !flag ) { /* Check if the command is an emote */ if( EMOTE_D->is_emote( cmd ) ) { string *rules; string rule; object target; rules = EMOTE_D->query_rules( cmd ); /* Targetted emote? Find the target */ if( arg != "" ) { target = this_environment()->find_object( arg ); } else { target = 0; } if( target != 0 ) { /* We've found our target, check for the correct rule */ if( target->is_living() ) { /* We're looking for a LIV rule */ if( member_array( "LIV", rules ) != -1 ) { rule = "LIV"; } else { rule = ""; } } else { /* We're looking for a OBJ rule */ if( member_array( "OBJ", rules ) != -1 ) { rule = "OBJ"; } else { rule = ""; } } } else { /* Or are we just looking for a string? */ if( member_array( "STR", rules ) != -1 && arg != "" ) { rule = "STR"; } else { rule = ""; } } if( rule == "LIV" ) { targetted_action( EMOTE_D->query_emote( cmd, rule ), target ); } else if( rule == "OBJ" ) { simple_action( EMOTE_D->query_emote( cmd, rule), target ); } else if( rule == "STR" ) { simple_action( EMOTE_D->query_emote( cmd, rule), arg ); } else { if( member_array( "", rules ) != -1 ) simple_action( EMOTE_D->query_emote( cmd, rule) ); else write( "No such emote.\n" ); } flag = 1; } } if( !flag ) { /* Is it a channel? */ if( CHANNEL_D->query_channel( cmd ) == 1 ) { /* Okey, it's a channel. Are we priveleged enough to use it? */ if( CHANNEL_D->query_priv( cmd )+1 == READ_ONLY || CHANNEL_D->query_priv( cmd ) <= SECURE_D->query_priv( player_name ) ) { flag = 1; CHANNEL_D->chan_cmd( cmd, arg ); } } } if( !flag ) { /* Is it an exit? */ exits = this_environment()->query_exit_indices(); for( i = 0; i < sizeof( exits ); i++ ) { if( exits[i] == lowercase( cmd ) ) { call_other( "/cmds/player/go", "main", cmd ); flag = 1; } } } if( !flag && cmd != "" ) { write( "What?\n" ); } if( !quitting && input_to_func == "" && !is_editing() ) write_prompt(); } }