コード例 #1
0
ファイル: lamu_skill.c プロジェクト: Zhanyin/taomee
int lahm_use_skill_do_work_cmd(sprite_t *p, const uint8_t *body, int bodylen)
{
	CHECK_VALID_ID(p->id);
	/*pet id, skill type, itemid*/
	CHECK_BODY_LEN(bodylen, 8);

	int j = 0;
	uint32_t skill_type;
	uint32_t skill_flag;
	UNPKG_UINT32(body, skill_type, j);

	if (p->followed == NULL) {
		return send_to_self_error(p, p->waitcmd, -ERR_the_lahm_not_followed, 1);
	}

	DEBUG_LOG("LAHM ACTION = %u %u %u %u", p->id, p->followed->id, p->lamu_action, skill_type);

	if (!PET_IS_SUPER_LAHM(p->followed)) {
		return send_to_self_error(p, p->waitcmd, -ERR_no_super_lahm, 1);
	}

	if (!check_skill(p, skill_type)) {
		return send_to_self_error(p, p->waitcmd, -ERR_lahm_have_not_this_skill, 1);
	}

	skill_flag = (skill_type - 1) % 3;
	if (p->lamu_action == 0 || (p->lamu_action -1) % 3 != skill_flag) {
		return send_to_self_error(p, p->waitcmd, -ERR_the_action_not_fit, 1);
	}

	uint32_t db_buf[7];

	db_buf[0] = skill_type;
	db_buf[1] = 0;
	db_buf[2] = 0;
	db_buf[3] = p->followed->id;
	db_buf[4] = 5;
	db_buf[5] = get_day_limit(p->followed);
	db_buf[6] = 1;

	*(uint32_t *)(p->session) = 0;
	*(uint32_t *)(p->session + 4) = db_buf[4];
	*(uint32_t *)(p->session + 8) = skill_type;

	return send_request_to_db(SVR_PROTO_GET_ITEM_BY_USER_SKILL, p, sizeof(db_buf), db_buf, p->id);
}
コード例 #2
0
ファイル: lamu_skill.c プロジェクト: Zhanyin/taomee
/* @brief lamu use skill broadcast
 */
int lamu_do_action_cmd(sprite_t *p, const uint8_t *body, int bodylen)
{
	CHECK_BODY_LEN(bodylen, 8);
	uint32_t action, petid;
	unpkg_uint32_uint32(body, bodylen, &petid, &action);

	if ((action > MAX_SKILL_NUM) || (action < 1) || (skill_items[action - 1].id ==0)) {
		ERROR_RETURN(("skill type wrong %u %u %u", p->id, action, MAX_SKILL_NUM), -1);
	}

	if (p->followed == NULL) {
		ERROR_RETURN(("no followed pet %u", p->id), -1);
	}
	pet_t *pet = p->followed;
	if ((pet->hungry == 0) || (pet->thirsty ==0)
		|| (pet->sanitary == 0) || (pet->spirit == 0)) {
		return send_to_self_error(p, p->waitcmd, -ERR_lahm_basic_attire_not_enough, 1);
	}
	/*check if have this skill*/
	if ((p->tiles->id != 126) && (p->tiles->id != 130) && (p->tiles->id != 134) )  {
		if (!check_skill(p, action)) {
			DEBUG_LOG("have not this skill %u %u", p->id, action);
			return send_to_self_error(p, p->waitcmd, -ERR_lahm_have_not_this_skill, 1);
		}
	}

	sub_lamu_basic_attire(p, p->followed, skill_items[action -1].sub_attr);

	p->lamu_action = action;
	p->lamu_action_timer = add_event(&(p->timer_list), lamu_end_action, p, p->followed,
							get_now_tv()->tv_sec + 20, ADD_EVENT_REPLACE_UNCONDITIONALLY);

	int i = sizeof(protocol_t);
	PKG_UINT32(msg, p->id, i);
	PKG_UINT32(msg, petid, i);
	PKG_UINT32(msg, action, i);
	PKG_UINT8(msg, pet->hungry, i);
	PKG_UINT8(msg, pet->thirsty, i);
	PKG_UINT8(msg, pet->sanitary, i);
	PKG_UINT8(msg, pet->spirit, i);
	init_proto_head(msg, PROTO_LAMU_ACTION, i);
	send_to_map(p, msg, i, 1);
	return 0;
}
コード例 #3
0
ファイル: interp.c プロジェクト: m241dan/W4M-Repo
/*
 * The main entry point for executing commands.
 * Can be recursively called from 'at', 'order', 'force'.
 */
void interpret( CHAR_DATA * ch, char *argument )
{
   char command[MAX_INPUT_LENGTH];
   char logline[MAX_INPUT_LENGTH];
   char logname[MAX_INPUT_LENGTH];
   char log_buf[MAX_STRING_LENGTH];
   char *origarg = argument;
   char *buf;
   TIMER *timer = NULL;
   CMDTYPE *cmd = NULL;
   int trust;
   int loglvl;
   bool found;
   struct timeval time_used;
   long tmptime;

   if( !ch )
   {
      bug( "%s: null ch!", __FUNCTION__ );
      return;
   }

   if( !ch->in_room )
   {
      bug( "%s: null in_room!", __FUNCTION__ );
      return;
   }

   found = FALSE;
   if( ch->substate == SUB_REPEATCMD )
   {
      DO_FUN *fun;

      if( ( fun = ch->last_cmd ) == NULL )
      {
         ch->substate = SUB_NONE;
         bug( "%s: SUB_REPEATCMD with NULL last_cmd", __FUNCTION__ );
         return;
      }
      else
      {
         int x;

         /*
          * yes... we lose out on the hashing speediness here...
          * but the only REPEATCMDS are wizcommands (currently)
          */
         for( x = 0; x < 126; x++ )
         {
            for( cmd = command_hash[x]; cmd; cmd = cmd->next )
               if( cmd->do_fun == fun )
               {
                  found = TRUE;
                  break;
               }
            if( found )
               break;
         }
         if( !found )
         {
            cmd = NULL;
            bug( "%s: SUB_REPEATCMD: last_cmd invalid", __FUNCTION__ );
            return;
         }
         snprintf( logline, MAX_INPUT_LENGTH, "(%s) %s", cmd->name, argument );
      }
   }

   if( !cmd )
   {
      /*
       * Changed the order of these ifchecks to prevent crashing. 
       */
      if( !argument || !strcmp( argument, "" ) )
      {
         bug( "%s: null argument!", __FUNCTION__ );
         return;
      }

      /*
       * Strip leading spaces.
       */
      while( isspace( *argument ) )
         argument++;
      if( argument[0] == '\0' )
         return;

      /*
       * xREMOVE_BIT( ch->affected_by, AFF_HIDE ); 
       */

      /*
       * Implement freeze command.
       */
      if( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_FREEZE ) )
      {
         send_to_char( "You're totally frozen!\r\n", ch );
         return;
      }

      /*
       * Grab the command word.
       * Special parsing so ' can be a command,
       *   also no spaces needed after punctuation.
       */
      mudstrlcpy( logline, argument, MAX_INPUT_LENGTH );
      if( !isalpha( argument[0] ) && !isdigit( argument[0] ) )
      {
         command[0] = argument[0];
         command[1] = '\0';
         argument++;
         while( isspace( *argument ) )
            argument++;
      }
      else
         argument = one_argument( argument, command );

      /*
       * Look for command in command table.
       * Check for council powers and/or bestowments
       */
      trust = get_trust( ch );
      for( cmd = command_hash[LOWER( command[0] ) % 126]; cmd; cmd = cmd->next )
         if( !str_prefix( command, cmd->name )
             && ( cmd->level <= trust
                  || ( !IS_NPC( ch ) && ch->pcdata->council
                       && is_name( cmd->name, ch->pcdata->council->powers )
                       && cmd->level <= ( trust + MAX_CPD ) )
                  || ( !IS_NPC( ch ) && ch->pcdata->bestowments && ch->pcdata->bestowments[0] != '\0'
                       && is_name( cmd->name, ch->pcdata->bestowments ) && cmd->level <= ( trust + sysdata.bestow_dif ) ) ) )
         {
            found = TRUE;
            break;
         }

      /*
       * Turn off afk bit when any command performed.
       */
      if( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_AFK ) && ( str_cmp( command, "AFK" ) ) )
      {
         xREMOVE_BIT( ch->act, PLR_AFK );
         act( AT_GREY, "$n is no longer afk.", ch, NULL, NULL, TO_CANSEE );
      }
   }

   /*
    * Log and snoop.
    */
   snprintf( lastplayercmd, ( MAX_INPUT_LENGTH * 2 ), "%s used %s", ch->name, logline );

   if( found && cmd->log == LOG_NEVER )
      mudstrlcpy( logline, "XXXXXXXX XXXXXXXX XXXXXXXX", MAX_INPUT_LENGTH );

   loglvl = found ? cmd->log : LOG_NORMAL;

   /*
    * Write input line to watch files if applicable
    */
   if( !IS_NPC( ch ) && ch->desc && valid_watch( logline ) )
   {
      if( found && IS_SET( cmd->flags, CMD_WATCH ) )
         write_watch_files( ch, cmd, logline );
      else if( IS_SET( ch->pcdata->flags, PCFLAG_WATCH ) )
         write_watch_files( ch, NULL, logline );
   }

   if( ( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_LOG ) )
       || fLogAll || loglvl == LOG_BUILD || loglvl == LOG_HIGH || loglvl == LOG_ALWAYS )
   {
      /*
       * Added by Narn to show who is switched into a mob that executes
       * a logged command.  Check for descriptor in case force is used. 
       */
      if( ch->desc && ch->desc->original )
         snprintf( log_buf, MAX_STRING_LENGTH, "Log %s (%s): %s", ch->name, ch->desc->original->name, logline );
      else
         snprintf( log_buf, MAX_STRING_LENGTH, "Log %s: %s", ch->name, logline );

      /*
       * Make it so a 'log all' will send most output to the log
       * file only, and not spam the log channel to death   -Thoric
       */
      if( fLogAll && loglvl == LOG_NORMAL && ( IS_NPC( ch ) || !xIS_SET( ch->act, PLR_LOG ) ) )
         loglvl = LOG_ALL;

      log_string_plus( log_buf, loglvl, get_trust( ch ) );
   }

   if( ch->desc && ch->desc->snoop_by )
   {
      snprintf( logname, MAX_INPUT_LENGTH, "%s", ch->name );
      write_to_buffer( ch->desc->snoop_by, logname, 0 );
      write_to_buffer( ch->desc->snoop_by, "% ", 2 );
      write_to_buffer( ch->desc->snoop_by, logline, 0 );
      write_to_buffer( ch->desc->snoop_by, "\r\n", 2 );
   }

   /*
    * check for a timer delayed command (search, dig, detrap, etc) 
    */
   if( ( timer = get_timerptr( ch, TIMER_DO_FUN ) ) != NULL )
   {
      int tempsub;

      tempsub = ch->substate;
      ch->substate = SUB_TIMER_DO_ABORT;
      ( timer->do_fun ) ( ch, "" );
      if( char_died( ch ) )
         return;
      if( ch->substate != SUB_TIMER_CANT_ABORT )
      {
         ch->substate = tempsub;
         extract_timer( ch, timer );
      }
      else
      {
         ch->substate = tempsub;
         return;
      }
   }

   /*
    * Look for command in skill and socials table.
    */
   if( !found )
   {
      if( !check_skill( ch, command, argument ) && !check_ability( ch, command, argument )   // Racial Abilities Support - Kayle 7-8-07
          && !rprog_command_trigger( ch, origarg )
          && !mprog_command_trigger( ch, origarg )
          && !oprog_command_trigger( ch, origarg )
          && !check_social( ch, command, argument ) && !news_cmd_hook( ch, command, argument )
#ifdef IMC
          && !imc_command_hook( ch, command, argument )
#endif
          )
      {
         EXIT_DATA *pexit;

         /*
          * check for an auto-matic exit command 
          */
         if( ( pexit = find_door( ch, command, TRUE ) ) != NULL && IS_SET( pexit->exit_info, EX_xAUTO ) )
         {
            if( IS_SET( pexit->exit_info, EX_CLOSED )
                && ( !IS_AFFECTED( ch, AFF_PASS_DOOR ) || IS_SET( pexit->exit_info, EX_NOPASSDOOR ) ) )
            {
               if( !IS_SET( pexit->exit_info, EX_SECRET ) )
                  act( AT_PLAIN, "The $d is closed.", ch, NULL, pexit->keyword, TO_CHAR );
               else
                  send_to_char( "You cannot do that here.\r\n", ch );
               return;
            }
            if( check_pos( ch, POS_STANDING ) )
               move_char( ch, pexit, 0 );
            return;
         }
         send_to_char( "Huh?\r\n", ch );
      }
      return;
   }

   /*
    * Character not in position for command?
    */
   if( !check_pos( ch, cmd->position ) )
      return;

   /*
    * Berserk check for flee.. maybe add drunk to this?.. but too much
    * hardcoding is annoying.. -- Altrag
    * This wasn't catching wimpy --- Blod
    * if ( !str_cmp(cmd->name, "flee") &&
    * IS_AFFECTED(ch, AFF_BERSERK) )
    * {
    * send_to_char( "You aren't thinking very clearly..\r\n", ch);
    * return;
    * } 
    */

   /*
    * So we can check commands for things like Posses and Polymorph
    * *  But still keep the online editing ability.  -- Shaddai
    * *  Send back the message to print out, so we have the option
    * *  this function might be usefull elsewhere.  Also using the
    * *  send_to_char_color so we can colorize the strings if need be. --Shaddai
    */

   buf = check_cmd_flags( ch, cmd );

   if( buf[0] != '\0' )
   {
      send_to_char_color( buf, ch );
      return;
   }

   /*
    * Nuisance stuff -- Shaddai
    */

   if( !IS_NPC( ch ) && ch->pcdata->nuisance && ch->pcdata->nuisance->flags > 9
       && number_percent(  ) < ( ( ch->pcdata->nuisance->flags - 9 ) * 10 * ch->pcdata->nuisance->power ) )
   {
      send_to_char( "You can't seem to do that just now.\r\n", ch );
      return;
   }

   /*
    * Dispatch the command.
    */
   ch->prev_cmd = ch->last_cmd;  /* haus, for automapping */
   ch->last_cmd = cmd->do_fun;
   start_timer( &time_used );
   ( *cmd->do_fun ) ( ch, argument );
   end_timer( &time_used );
   /*
    * Update the record of how many times this command has been used (haus)
    */
   update_userec( &time_used, &cmd->userec );
   tmptime = UMIN( time_used.tv_sec, 19 ) * 1000000 + time_used.tv_usec;

   /*
    * laggy command notice: command took longer than 1.5 seconds 
    */
   if( tmptime > 1500000 )
   {
      log_printf_plus( LOG_NORMAL, get_trust( ch ), "[*****] LAG: %s: %s %s (R:%d S:%ld.%06ld)", ch->name,
                       cmd->name, ( cmd->log == LOG_NEVER ? "XXX" : argument ),
                       ch->in_room ? ch->in_room->vnum : 0, time_used.tv_sec, time_used.tv_usec );
      cmd->lag_count++; /* count the lag flags */
   }

   tail_chain(  );
}
コード例 #4
0
ファイル: lamu_skill.c プロジェクト: Zhanyin/taomee
/* @breif add item by use skill
 */
int get_item_by_skill_cmd(sprite_t *p, const uint8_t *body, int bodylen)
{
	CHECK_VALID_ID(p->id);
	/*pet id, skill type, itemid*/
	CHECK_BODY_LEN(bodylen, 12);

	if (p->followed == NULL) {
			ERROR_RETURN(("not followed lamu %u", p->id), -1);
	}

	uint32_t petid, skill_type, itemid;
	int j = 0;
	UNPKG_UINT32(body, petid, j);
	UNPKG_UINT32(body, skill_type, j);
	if ((skill_type > MAX_SKILL_NUM) || (skill_type < 1) || (skill_items[skill_type - 1].id ==0)) {
		ERROR_RETURN(("skill type wrong %u %u %u", p->id, skill_type, MAX_SKILL_NUM), -1);
	}
	UNPKG_UINT32(body, itemid, j);
	int item_skill_type = 0;
	if (!check_itemid(p, itemid, skill_type, &item_skill_type)) {
		ERROR_RETURN(("wrong itemid %u %u %u %u", p->id, skill_type, itemid, item_skill_type), -1);
	}
	/*ID号为零直接返回*/
	if (itemid == 0) {
		int i = sizeof(protocol_t);
		PKG_UINT32(msg, 0, i);
		PKG_UINT32(msg, p->followed->skill_value, i);
		init_proto_head(msg, p->waitcmd, i);
		return  send_to_self(p, msg, i, 1);
	}

	/*save item id, add change value, skill type*/
	*(uint32_t *)(p->session) = itemid;
	*(uint32_t *)(p->session + 8) = skill_type;
	/*check if have this skill, 126 map not check*/
	uint32_t not_check = (p->tiles->id == 126 && itemid == 190591)
						|| (p->tiles->id == 130 && itemid == 190611)
						|| (p->tiles->id == 134 && itemid == 190625);


	if (!not_check) {
		/*lamu should do action*/
		if (p->lamu_action == 0) {
			DEBUG_LOG("lamu action zero %u", p->id);
			return send_to_self_error(p, p->waitcmd, -ERR_action_have_fini, 1);
		}
		if (!check_skill(p, skill_type)) {
			DEBUG_LOG("have not this skill %u %u", p->id, skill_type);
			return send_to_self_error(p, p->waitcmd, -ERR_lahm_have_not_this_skill, 1);
		}
	}
	uint32_t day_limit = 0;
	if (ISVIP(p->flag)) {
		day_limit = skill_items[item_skill_type - 1].vip_limit;
	} else {
		day_limit = skill_items[item_skill_type -1].pl_limit;
	}

	uint32_t db_buf[7];
	db_buf[0] = item_skill_type;
	db_buf[1] = itemid;
	db_buf[2] = day_limit;
	db_buf[3] = p->followed->id;
	if (check_skill(p, skill_type)) {
		int add_change = skill_items[skill_type - 1].add_change;
		if (PET_IS_SUPER_LAHM(p->followed)) {
			add_change *= 2;
		}
		db_buf[4] = add_change;
		db_buf[5] = get_day_limit(p->followed);
		*(uint32_t *)(p->session + 4) = add_change;
	} else {
		*(uint32_t *)(p->session + 4) = 0;
		db_buf[4] = 0;
		db_buf[5] = 0;
	}
	db_buf[6] = 0;
	return send_request_to_db(SVR_PROTO_GET_ITEM_BY_USER_SKILL, p, sizeof(db_buf), db_buf, p->id);
}
コード例 #5
0
ファイル: interp.c プロジェクト: AndrewBudd/swr-fuss-ace
/*
 * The main entry point for executing commands.
 * Can be recursively called from 'at', 'order', 'force'.
 */
void interpret( CHAR_DATA * ch, const char *argument )
{
   char command[MAX_INPUT_LENGTH];
   char logline[MAX_INPUT_LENGTH];
   char logname[MAX_INPUT_LENGTH];
   TIMER *timer = NULL;
   CMDTYPE *cmd = NULL;
   int trust;
   int loglvl;
   bool found;
   struct timeval time_used;
   long tmptime;


   if( !ch )
   {
      bug( "interpret: null ch!", 0 );
      return;
   }

   found = FALSE;
   if( ch->substate == SUB_REPEATCMD )
   {
      DO_FUN *fun;

      if( ( fun = ch->last_cmd ) == NULL )
      {
         ch->substate = SUB_NONE;
         bug( "interpret: SUB_REPEATCMD with NULL last_cmd", 0 );
         return;
      }
      else
      {
         int x;

         /*
          * yes... we lose out on the hashing speediness here...
          * but the only REPEATCMDS are wizcommands (currently)
          */
         for( x = 0; x < 126; x++ )
         {
            for( cmd = command_hash[x]; cmd; cmd = cmd->next )
               if( cmd->do_fun == fun )
               {
                  found = TRUE;
                  break;
               }
            if( found )
               break;
         }
         if( !found )
         {
            cmd = NULL;
            bug( "interpret: SUB_REPEATCMD: last_cmd invalid", 0 );
            return;
         }
         sprintf( logline, "(%s) %s", cmd->name, argument );
      }
   }

   if( !cmd )
   {
      /*
       * Changed the order of these ifchecks to prevent crashing. 
       */
      if( !argument || !strcmp( argument, "" ) )
      {
         bug( "interpret: null argument!", 0 );
         return;
      }

      /*
       * Strip leading spaces.
       */
      while( isspace( *argument ) )
         argument++;
      if( argument[0] == '\0' )
         return;

      timer = get_timerptr( ch, TIMER_DO_FUN );

      /*
       * REMOVE_BIT( ch->affected_by, AFF_HIDE ); 
       */

      /*
       * Implement freeze command.
       */
      if( !IS_NPC( ch ) && IS_SET( ch->act, PLR_FREEZE ) )
      {
         send_to_char( "You're totally frozen!\r\n", ch );
         return;
      }

      /*
       * Grab the command word.
       * Special parsing so ' can be a command,
       *   also no spaces needed after punctuation.
       */
      strcpy( logline, argument );
      if( !isalpha( argument[0] ) && !isdigit( argument[0] ) )
      {
         command[0] = argument[0];
         command[1] = '\0';
         argument++;
         while( isspace( *argument ) )
            argument++;
      }
      else
         argument = one_argument( argument, command );

      /*
       * Look for command in command table.
       * Check for council powers and/or bestowments
       */
      trust = get_trust( ch );
      for( cmd = command_hash[LOWER( command[0] ) % 126]; cmd; cmd = cmd->next )
         if( !str_prefix( command, cmd->name )
             && ( cmd->level <= trust
                  || ( !IS_NPC( ch ) && ch->pcdata->bestowments && ch->pcdata->bestowments[0] != '\0'
                       && is_name( cmd->name, ch->pcdata->bestowments ) && cmd->level <= ( trust + 5 ) ) ) )
         {
            found = TRUE;
            break;
         }

      /*
       * Turn off afk bit when any command performed.
       */
      if( !IS_NPC( ch ) && IS_SET( ch->act, PLR_AFK ) && ( str_cmp( command, "AFK" ) ) )
      {
         REMOVE_BIT( ch->act, PLR_AFK );
         act( AT_GREY, "$n is no longer afk.", ch, NULL, NULL, TO_ROOM );
      }
   }

   /*
    * Log and snoop.
    */
   sprintf( lastplayercmd, "** %s: %s", ch->name, logline );

   if( found && cmd->log == LOG_NEVER )
      strcpy( logline, "XXXXXXXX XXXXXXXX XXXXXXXX" );

   loglvl = found ? cmd->log : LOG_NORMAL;

   if( ( !IS_NPC( ch ) && IS_SET( ch->act, PLR_LOG ) )
       || fLogAll || loglvl == LOG_BUILD || loglvl == LOG_HIGH || loglvl == LOG_ALWAYS )
   {
      /*
       * Added by Narn to show who is switched into a mob that executes
       * a logged command.  Check for descriptor in case force is used. 
       */
      if( ch->desc && ch->desc->original )
         sprintf( log_buf, "Log %s (%s): %s", ch->name, ch->desc->original->name, logline );
      else
         sprintf( log_buf, "Log %s: %s", ch->name, logline );

      /*
       * Make it so a 'log all' will send most output to the log
       * file only, and not spam the log channel to death   -Thoric
       */
      if( fLogAll && loglvl == LOG_NORMAL && ( IS_NPC( ch ) || !IS_SET( ch->act, PLR_LOG ) ) )
         loglvl = LOG_ALL;

      /*
       * This is handled in get_trust already 
       */
/*	if ( ch->desc && ch->desc->original )
	  log_string_plus( log_buf, loglvl,
		ch->desc->original->level );
	else*/
      log_string_plus( log_buf, loglvl, get_trust( ch ) );
   }

   if( ch->desc && ch->desc->snoop_by )
   {
      sprintf( logname, "%s", ch->name );
      write_to_buffer( ch->desc->snoop_by, logname, 0 );
      write_to_buffer( ch->desc->snoop_by, "% ", 2 );
      write_to_buffer( ch->desc->snoop_by, logline, 0 );
      write_to_buffer( ch->desc->snoop_by, "\r\n", 2 );
   }



   if( timer )
   {
      int tempsub;

      tempsub = ch->substate;
      ch->substate = SUB_TIMER_DO_ABORT;
      ( timer->do_fun ) ( ch, "" );
      if( char_died( ch ) )
         return;
      if( ch->substate != SUB_TIMER_CANT_ABORT )
      {
         ch->substate = tempsub;
         extract_timer( ch, timer );
      }
      else
      {
         ch->substate = tempsub;
         return;
      }
   }

   /*
    * Look for command in skill and socials table.
    */
   if( !found )
   {
      if( !check_skill( ch, command, argument ) && !check_social( ch, command, argument )
#ifdef IMC
          && !imc_command_hook( ch, command, argument )
#endif
          )
      {
         EXIT_DATA *pexit;

         /*
          * check for an auto-matic exit command 
          */
         if( ( pexit = find_door( ch, command, TRUE ) ) != NULL && IS_SET( pexit->exit_info, EX_xAUTO ) )
         {
            if( IS_SET( pexit->exit_info, EX_CLOSED )
                && ( !IS_AFFECTED( ch, AFF_PASS_DOOR ) || IS_SET( pexit->exit_info, EX_NOPASSDOOR ) ) )
            {
               if( !IS_SET( pexit->exit_info, EX_SECRET ) )
                  act( AT_PLAIN, "The $d is closed.", ch, NULL, pexit->keyword, TO_CHAR );
               else
                  send_to_char( "You cannot do that here.\r\n", ch );
               return;
            }
            move_char( ch, pexit, 0 );
            return;
         }
         send_to_char( "Huh?\r\n", ch );
      }
      return;
   }

   /*
    * Character not in position for command?
    */
   if( !check_pos( ch, cmd->position ) )
      return;

   /*
    * Berserk check for flee.. maybe add drunk to this?.. but too much
    * hardcoding is annoying.. -- Altrag 
    */
   if( !str_cmp( cmd->name, "flee" ) && IS_AFFECTED( ch, AFF_BERSERK ) )
   {
      send_to_char( "You aren't thinking very clearly..\r\n", ch );
      return;
   }

   /*
    * Dispatch the command.
    */
   ch->prev_cmd = ch->last_cmd;  /* haus, for automapping */
   ch->last_cmd = cmd->do_fun;
   start_timer( &time_used );
   ( *cmd->do_fun ) ( ch, argument );
   end_timer( &time_used );
   /*
    * Update the record of how many times this command has been used (haus)
    */
   update_userec( &time_used, &cmd->userec );
   tmptime = UMIN( time_used.tv_sec, 19 ) * 1000000 + time_used.tv_usec;

   /*
    * laggy command notice: command took longer than 1.5 seconds 
    */
   if( tmptime > 1500000 )
   {
      sprintf( log_buf, "[*****] LAG: %s: %s %s (R:%d S:%d.%06d)", ch->name,
               cmd->name, ( cmd->log == LOG_NEVER ? "XXX" : argument ),
               ch->in_room ? ch->in_room->vnum : 0, ( int )( time_used.tv_sec ), ( int )( time_used.tv_usec ) );
      log_string_plus( log_buf, LOG_NORMAL, get_trust( ch ) );
   }

   tail_chain(  );
}