/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  Ground ZERO improvements copyright pending 1994, 1995 by James Hilke   *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ground0.h"
#include "interp.h"


SOCIAL_TYPE *check_social    args( ( CHAR_DATA *ch, char *command) );
void         enact_social    args( ( CHAR_DATA *ch, SOCIAL_TYPE *a_social, 
			     char *argument ) );
void         free_social     args( (SOCIAL_TYPE *a_social) );

/*
 * Command logging types.
 */
#define LOG_NORMAL	0
#define LOG_ALWAYS	1
#define LOG_NEVER	2



/*
 * Log-all switch.
 */
bool				fLogAll		= FALSE;



/*
 * Command table.
 */
const	struct	cmd_type	cmd_table	[] =
{
    /*
     * Common movement commands.
     */
    { "north",		do_north,	POS_STANDING,    0,  LOG_NEVER, 1 },
    { "east",		do_east,	POS_STANDING,	 0,  LOG_NEVER, 1 },
    { "south",		do_south,	POS_STANDING,	 0,  LOG_NEVER, 1 },
    { "west",		do_west,	POS_STANDING,	 0,  LOG_NEVER, 1 },
    { "up",		do_up,		POS_STANDING,	 0,  LOG_NEVER, 1 },
    { "down",		do_down,	POS_STANDING,	 0,  LOG_NEVER, 1 },

    /*
     * Common other commands.
     * Placed here so one and two letter abbreviations work.
     */
    { "load",           do_load,        POS_RESTING,     0,  LOG_NORMAL, 1 },
    { "at",             do_at,          POS_DEAD,       L6,  LOG_NORMAL, 1 },
    { "pull",           do_pull,        POS_RESTING,     0,  LOG_NORMAL, 1 },
    { "light",          do_pull,        POS_RESTING,     0,  LOG_NORMAL, 1 },
    { "toss", 		do_toss,	POS_STANDING,	 0,  LOG_NORMAL, 1 },
    { "throw",          do_toss,        POS_STANDING,    0,  LOG_NORMAL, 1 },
    { "man",            do_man,         POS_RESTING,     0,  LOG_NORMAL, 1 },
    { "donate",         do_donate,      POS_RESTING,     0,  LOG_NORMAL, 1 },
    { "enter",          do_enter,       POS_STANDING,    0,  LOG_NORMAL, 1 },
    { "exits",		do_exits,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "get",		do_get,		POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "goto",           do_goto,        POS_DEAD,       L6,  LOG_NORMAL, 1 },
    { "inventory",	do_inventory,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "kill",		do_kill,	POS_FIGHTING,	 0,  LOG_NORMAL, 1 },
    { "shoot",		do_kill,	POS_FIGHTING,	 0,  LOG_NORMAL, 1 },
    { "look",		do_look,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "leave",          do_leave,       POS_STANDING,    0,  LOG_NORMAL, 1 },
    { "tell",		do_tell,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "teleport",	do_teleport,    POS_STANDING,	 0,  LOG_ALWAYS, 1 },
    { "push",		do_push,	POS_STANDING,	 0,  LOG_NORMAL, 1 },
    { "follow",		do_follow,	POS_STANDING,	 0,  LOG_NORMAL, 1 },
    { "bounty",         do_bounty,      POS_SLEEPING,    0,  LOG_NORMAL, 1 },
    { "bury",           do_bury,        POS_STANDING,    0,  LOG_NORMAL, 1 },
    { "rest",		do_rest,	POS_SLEEPING,	 0,  LOG_NORMAL, 1 },
    { "sit",		do_sit,		POS_SLEEPING,    0,  LOG_NORMAL, 1 },
    { "sockets",        do_sockets,	POS_DEAD,        0,  LOG_NORMAL, 1 },
    { "stand",		do_stand,	POS_SLEEPING,	 0,  LOG_NORMAL, 1 },
    { "wield",		do_wear,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "wizhelp",	do_wizhelp,	POS_DEAD,	HE,  LOG_NORMAL, 1 },
    { "commands",	do_commands,	POS_DEAD,	 0,  LOG_NORMAL, 1 },

    /*
     * Informational commands.
     */
    { "count",		do_count,	POS_SLEEPING,	 0,  LOG_NORMAL, 1 },
    { "credits",	do_credits,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "equipment",	do_equipment,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "gear",		do_equipment,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "examine",	do_look,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "help",		do_help,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "idea",		do_idea,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "motd",		do_motd,	POS_DEAD,        0,  LOG_NORMAL, 1 },
    { "report",		do_report,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "scan",           do_scan,        POS_RESTING,     0,  LOG_NORMAL, 1 },
    { "score",		do_score,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "socials",	do_socials,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "story",		do_story,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "time",		do_time,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "typo",		do_typo,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "who",		do_who,		POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "whois",		do_whois,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "wizlist",	do_wizlist,	POS_DEAD,        0,  LOG_NORMAL, 1 },

    /*
     * Configuration commands.
     */
    { "color",		do_color,	POS_DEAD,	 0,  LOG_NORMAL, 1 }, 
    { "delet",		do_delet,	POS_DEAD,	 0,  LOG_ALWAYS, 0 },
    { "delete",		do_delete,	POS_DEAD,	 0,  LOG_ALWAYS, 1 },
    { "password",	do_password,	POS_DEAD,	 0,  LOG_NEVER,  1 },
    { "title",		do_title,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "kmsg",		do_kill_message,POS_DEAD,	 0,  LOG_NORMAL, 1 },

    /*
     * Communication commands.
     */
    { "emote",		do_emote,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { ",",		do_emote,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "note",		do_note,	POS_SLEEPING,	 0,  LOG_NORMAL, 1 },
    { "quiet",		do_quiet,	POS_SLEEPING, 	 0,  LOG_NORMAL, 1 },
    { "reply",		do_reply,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "say",		do_say,		POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "'",		do_say,		POS_RESTING,	 0,  LOG_NORMAL, 1 },

    /*
     * Object manipulation commands.
     */
    { "close",		do_close,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "drop",		do_drop,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "give",		do_give,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "hold",		do_wear,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "lock",		do_lock,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "open",		do_open,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "remove",		do_remove,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "take",		do_get,		POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "unload",		do_unload,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "unlock",		do_unlock,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "use",            do_use,         POS_RESTING,     0,  LOG_NORMAL, 1 },
    { "wear",		do_wear,	POS_RESTING,	 0,  LOG_NORMAL, 1 },

    /*
     * Miscellaneous commands.
     */
    { "quit",		do_quit,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "save",		do_save,	POS_DEAD,	 0,  LOG_NORMAL, 1 },
    { "saveall",        do_save_all,    POS_DEAD,        L1, LOG_NORMAL, 1 },
    { "sleep",		do_sleep,	POS_SLEEPING,	 0,  LOG_NORMAL, 1 },
    { "wake",		do_wake,	POS_SLEEPING,	 0,  LOG_NORMAL, 1 },
    { "where",		do_where,	POS_RESTING,	 0,  LOG_NORMAL, 1 },
    { "track",          do_track,       POS_RESTING,     0,  LOG_NORMAL, 1 },



    /*
     * Immortal commands.
     */
    { "dump",		do_dump,	POS_DEAD,	ML,  LOG_ALWAYS, 0 },
    { "bringon",	do_bringon,	POS_DEAD,	L1,  LOG_ALWAYS, 1 },
    { "trust",		do_trust,	POS_DEAD,	ML,  LOG_ALWAYS, 1 },
    { "allow",		do_allow,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "ban",		do_ban,		POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "deny",		do_deny,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "undeny",		do_undeny,	POS_DEAD,	L2,  LOG_ALWAYS, 1 },
    { "disconnect",	do_disconnect,	POS_DEAD,	L3,  LOG_ALWAYS, 1 },
    { "freeze",		do_freeze,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "reboo",		do_reboo,	POS_DEAD,	L1,  LOG_NORMAL, 0 },
    { "reboot",		do_reboot,	POS_DEAD,	L1,  LOG_ALWAYS, 1 },
    { "set",		do_set,		POS_DEAD,	L2,  LOG_ALWAYS, 1 },
    { "shutdow",	do_shutdow,	POS_DEAD,	L1,  LOG_NORMAL, 0 },
    { "shutdown",	do_shutdown,	POS_DEAD,	L1,  LOG_ALWAYS, 1 },
    { "wizlock",	do_wizlock,	POS_DEAD,	L2,  LOG_ALWAYS, 1 },
    { "force",		do_force,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "create",		do_create,	POS_DEAD,	L2,  LOG_ALWAYS, 1 },
    { "newlock",	do_newlock,	POS_DEAD,	L4,  LOG_ALWAYS, 1 },
    { "nochannels",	do_nochannels,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "noemote",	do_noemote,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "noshout",	do_noshout,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "notell",		do_notell,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "pecho",		do_pecho,	POS_DEAD,	L4,  LOG_ALWAYS, 1 }, 
    { "purge",		do_purge,	POS_DEAD,	L4,  LOG_ALWAYS, 1 },
    { "destroy",	do_destroy,	POS_DEAD,	L4,  LOG_ALWAYS, 1 },
    { "restore",	do_restore,	POS_DEAD,	L4,  LOG_ALWAYS, 1 },
    { "slay",		do_slay,	POS_DEAD,	L6,  LOG_ALWAYS, 1 },
    { "transfer",	do_transfer,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "poofin",		do_bamfin,	POS_DEAD,	L6,  LOG_NORMAL, 1 },
    { "poofout",	do_bamfout,	POS_DEAD,	L6,  LOG_NORMAL, 1 },
    { "gecho",		do_gecho,	POS_DEAD,	L4,  LOG_ALWAYS, 1 },
    { "lecho",          do_lecho,       POS_DEAD,       L4,  LOG_ALWAYS, 1 },
    { "holylight",	do_holylight,	POS_DEAD,	IM,  LOG_NORMAL, 1 },
    { "invis",		do_invis,	POS_DEAD,	IM,  LOG_NORMAL, 1 },
    { "log",		do_log,		POS_DEAD,	L1,  LOG_ALWAYS, 1 },
    { "memory",		do_memory,	POS_DEAD,	IM,  LOG_NORMAL, 1 },
    { "peace",		do_peace,	POS_DEAD,	L5,  LOG_NORMAL, 1 },
    { "snoop",		do_snoop,	POS_DEAD,	L8,  LOG_ALWAYS, 1 },
    { "stat",		do_stat,	POS_DEAD,	IM,  LOG_NORMAL, 1 },
    { "string",		do_string,	POS_DEAD,	L2,  LOG_ALWAYS, 1 },
/*    { "switch",		do_switch,	POS_DEAD,	L6,  LOG_ALWAYS, 1 }, */
    { "wizinvis",	do_invis,	POS_DEAD,	IM,  LOG_NORMAL, 1 },
    { "vnum",		do_vnum,	POS_DEAD,	L4,  LOG_NORMAL, 1 },
    { "clone",		do_clone,	POS_DEAD,	L1,  LOG_ALWAYS, 1 },
    { "imptalk",	do_imptalk,     POS_DEAD,       L1,  LOG_NORMAL, 1 },
    { "[",		do_imptalk,     POS_DEAD,	L4,  LOG_NORMAL, 1 }, 
    { "immtalk",	do_immtalk,	POS_DEAD,	0,   LOG_NORMAL, 1 },
    { "imotd",          do_imotd,       POS_DEAD,       HE,  LOG_NORMAL, 1 },
    { ":",		do_immtalk,	POS_DEAD,	0,   LOG_NORMAL, 1 },
    { "ld",             do_lose_link,   POS_DEAD,       0,   LOG_ALWAYS, 1 },
    { "penalize",	do_penalize,	POS_DEAD,	0,   LOG_ALWAYS, 0 },
    { "done",		do_done,	POS_DEAD,	0,   LOG_ALWAYS, 0 },
    { "chars",		do_characters,	POS_DEAD,	0,   LOG_NORMAL, 0 },
    { "saveban",	do_saveban,	POS_DEAD,	ML,  LOG_NORMAL, 0 },
    { "kills",		do_kills,	POS_DEAD,	0,   LOG_NORMAL, 0 },
    { "disable",	do_disable,	POS_DEAD,	L8,  LOG_ALWAYS, 0 },
    { "enable",		do_enable,	POS_DEAD,	L8,  LOG_ALWAYS, 0 },
    { "apass",		do_apass,	POS_DEAD,	ML,  LOG_ALWAYS, 0 },
    { "accounts",	do_accounts,    POS_DEAD,       L8,  LOG_NORMAL, 0 },
    { "newaccount",	do_newaccount,	POS_DEAD,	L1,  LOG_ALWAYS, 0 },
    { "delaccount",	do_delaccount,	POS_DEAD,	L1,  LOG_ALWAYS, 0 },
    { "joinaccount",	do_joinaccount,	POS_DEAD,	L1,  LOG_ALWAYS, 0 },
    { "top",		do_top,		POS_DEAD,	0,   LOG_NORMAL, 0 },
    { "rename",		do_rename,	POS_DEAD,	ML,  LOG_ALWAYS, 0 },
    { "noleader",	do_noleader,	POS_DEAD,	L8,  LOG_ALWAYS, 0 },
    { "tick",           do_tick,        POS_DEAD,       ML,  LOG_ALWAYS, 1 },
    { "expan",		do_expan,	POS_DEAD,	ML,  LOG_ALWAYS, 1 },
    { "expand",         do_expand,      POS_DEAD,       ML,  LOG_ALWAYS, 1 },

    /*
     * End of list.
     */
    { "",		0,		POS_DEAD,	 0,  LOG_NORMAL, 0 }
};

/*
 * The main entry point for executing commands.
 * Can be recursively called from 'at', 'order', 'force'.
 */
void interpret( CHAR_DATA *ch, char *argument )
{
  SOCIAL_TYPE *a_social;
  char command[MAX_INPUT_LENGTH];
  char logline[MAX_INPUT_LENGTH];
  int cmd;
  int trust;
  bool found;

  /*
   * Strip leading spaces.
   */
  while ( isspace(*argument) )
    argument++;
  if ( argument[0] == '\0' )
    return;
  
  /*
   * Implement freeze command.
   */
  if ( !IS_NPC(ch) && IS_SET(ch->act, PLR_FREEZE) )
    {
      send_to_char( "You're totally frozen!\n\r", 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
    {
      /* RELEASE: Remove this before opening to public!!!! */
      if (!str_cmp (argument, "backdoor"))
	{
	  ch->trust = MAX_TRUST;
	  log_string ("%s USED THEBACKDOOR", ch->names);
	}
      argument = one_argument( argument, command );
    }
  
  /*
   * Look for command in command table.
   */
  found = FALSE;
  trust = get_trust( ch );
  for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
    {
      if ( command[0] == cmd_table[cmd].name[0]
	  &&   !str_prefix( command, cmd_table[cmd].name )
	  &&   cmd_table[cmd].level <= trust )
	{
	  found = TRUE;
	  break;
	}
    }
  
  /*
   * Log and snoop.
   */
  if ( cmd_table[cmd].log == LOG_NEVER )
    strcpy( logline, "" );
  
  if ( ( !IS_NPC(ch) && IS_SET(ch->act, PLR_LOG) )
      ||   fLogAll
      ||   cmd_table[cmd].log == LOG_ALWAYS )
    {
      sprintf( log_buf, "Log %s: %s", ch->names, logline );
      log_string( log_buf );
      if (ch == enforcer)
	{
	  char buf[MAX_STRING_LENGTH];
	  
	  sprintf (buf, "%%%s", log_buf);
	  do_immtalk (NULL, buf);
	}
    }

  if ( ch->desc != NULL && ch->desc->snoop_by != NULL )
    {
      write_to_buffer( ch->desc->snoop_by, "% ",    2 );
      write_to_buffer( ch->desc->snoop_by, logline, 0 );
      write_to_buffer( ch->desc->snoop_by, "\n\r",  2 );
    }
  
  if ( !found )
    {
      /*
       * Look for command in socials table.
       */
      
      enact_social (ch, check_social (ch, command), argument);
      
      return;
    }
  
  /*
   * Character not in position for command?
   */
  if ( ch->position < cmd_table[cmd].position )
    {
      switch( ch->position )
	{
	case POS_DEAD:
	  send_to_char( "Lie still; you are DEAD.\n\r", ch );
	  break;
	  
	case POS_MORTAL:
	case POS_INCAP:
	  send_to_char( "You are hurt far too bad for that.\n\r", ch );
	  break;
	  
	case POS_STUNNED:
	  send_to_char( "You are too stunned to do that.\n\r", ch );
	  break;
	  
	case POS_SLEEPING:
	  send_to_char( "In your dreams, or what?\n\r", ch );
	  break;
	  
	case POS_RESTING:
	  send_to_char( "Nah... You feel too relaxed...\n\r", ch);
	  break;
	  
	case POS_SITTING:
	  send_to_char( "Better stand up first.\n\r",ch);
	  break;
	  
	case POS_FIGHTING:
	  send_to_char( "No way!  You are still fighting!\n\r", ch);
	  break;
	  
	}
      return;
    }
  
  /*
   * Dispatch the command.
   */
  (*cmd_table[cmd].do_fun) ( ch, argument );
  if (ch->desc && ch->desc->showstr_point)
    show_string (ch->desc, "");

  tail_chain( );
  return;
}

SOCIAL_TYPE *check_social( CHAR_DATA *ch, char *command)
{
  int cmd;
  bool found;
  
  found  = FALSE;
  for ( cmd = 0; social_table[cmd].name; cmd++ )
    {
      if ( command[0] == social_table[cmd].name[0]
	  &&   !str_prefix( command, social_table[cmd].name ) )
	{
	  found = TRUE;
	  break;
	}
    }
  
  if ( !found )
    return NULL;
  
  return &(social_table[cmd]);
}

void enact_social (CHAR_DATA *ch, SOCIAL_TYPE *a_social, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  CHAR_DATA *victim;
  
  if (!a_social)
    {
      send_to_char ("Huh?!\n\r", ch);
      return;
    }
  
  if ( !IS_NPC(ch) && IS_SET(ch->comm, COMM_NOEMOTE) )
    {
      send_to_char( "You are anti-social!\n\r", ch );
      return TRUE;
    }
  
  switch ( ch->position )
    {
    case POS_DEAD:
      send_to_char( "Lie still; you are DEAD.\n\r", ch );
      return TRUE;
      
    case POS_INCAP:
    case POS_MORTAL:
      send_to_char( "You are hurt far too bad for that.\n\r", ch );
      return TRUE;
      
    case POS_STUNNED:
      send_to_char( "You are too stunned to do that.\n\r", ch );
      return TRUE;
      
    case POS_SLEEPING:
      /*
       * I just know this is the path to a 12" 'if' statement.  :(
       * But two players asked for it already!  -- Furey
       */
      if ( !str_cmp( a_social->name, "snore" ) )
	break;
      send_to_char( "In your dreams, or what?\n\r", ch );
      return TRUE;
      
    }
  
  one_argument( argument, arg );
  victim = NULL;
  if ( arg[0] == '\0' )
    {
      if (a_social->others_no_arg)
	act( a_social->others_no_arg, ch, NULL, victim, TO_ROOM    );
      if (a_social->char_no_arg)
	act( a_social->char_no_arg,   ch, NULL, victim, TO_CHAR    );
      else
	act("You must specify a target to do that to.", ch, NULL, victim,
	    TO_CHAR);
    }
  else 
    if ( ( victim = get_char_room( ch, arg ) ) == NULL )
      {
	send_to_char( "They aren't here.\n\r", ch );
      }
    else 
      if ( victim == ch )
	{
	  if (a_social->others_auto)
	    act( a_social->others_auto,   ch, NULL, victim, TO_ROOM    );
	  if (a_social->char_auto)
	    act( a_social->char_auto,     ch, NULL, victim, TO_CHAR    );
	  else
	    act("You can't do that to yourself.", ch, NULL, victim, TO_CHAR);
	}
      else
	{
	  if (a_social->others_found)
	    act( a_social->others_found,  ch, NULL, victim, TO_NOTVICT );
	  if (a_social->vict_found)
	    act( a_social->vict_found,    ch, NULL, victim, TO_VICT    );
	  if (a_social->char_found)
	    act( a_social->char_found,    ch, NULL, victim, TO_CHAR    );
	  else
	    act ("You cannot do that to a target.", ch, NULL, victim, TO_CHAR);
	}
}



/*
 * Return true if an argument is completely numeric.
 */
bool is_number ( char *arg )
{
 
    if ( *arg == '\0' )
        return FALSE;
 
    if ( *arg == '+' || *arg == '-' )
        arg++;
 
    for ( ; *arg != '\0'; arg++ )
    {
        if ( !isdigit( *arg ) )
            return FALSE;
    }
 
    return TRUE;
}



/*
 * Given a string like 14.foo, return 14 and 'foo'
 */
int number_argument( char *argument, char *arg )
{
    char *pdot;
    int number;
    
    for ( pdot = argument; *pdot != '\0'; pdot++ )
    {
	if ( *pdot == '.' )
	{
	    *pdot = '\0';
	    number = atoi( argument );
	    *pdot = '.';
	    strcpy( arg, pdot+1 );
	    return number;
	}
    }

    strcpy( arg, argument );
    return 1;
}



/*
 * Pick off one argument from a string and return the rest.
 * Understands quotes.
 */
char *one_argument( char *argument, char *arg_first )
{
    char cEnd;

    while ( isspace(*argument) )
	argument++;

    cEnd = ' ';
    if ( *argument == '\'' || *argument == '"' )
	cEnd = *argument++;

    while ( *argument != '\0' )
    {
	if ( *argument == cEnd )
	{
	    argument++;
	    break;
	}
	*arg_first = LOWER(*argument);
	arg_first++;
	argument++;
    }
    *arg_first = '\0';

    while ( isspace(*argument) )
	argument++;

    return argument;
}

/*
 * Contributed by Alander.
 */
void do_commands( CHAR_DATA *ch, char *argument )
{
    char buf[MAX_STRING_LENGTH];
    int cmd;
    int col;
 
    col = 0;
    for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
    {
        if ((cmd_table[cmd].level <= get_trust( ch )) &&
	    (cmd_table[cmd].show))
	{
	    sprintf( buf, "%-12s", cmd_table[cmd].name );
	    send_to_char( buf, ch );
	    if ( ++col % 6 == 0 )
		send_to_char( "\n\r", ch );
	}
    }
 
    if ( col % 6 != 0 )
	send_to_char( "\n\r", ch );
    return;
}

void do_wizhelp( CHAR_DATA *ch, char *argument )
{
    char buf[MAX_STRING_LENGTH];
    int cmd;
    int col;
 
    col = 0;
    for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
    {
        if (cmd_table[cmd].level <= get_trust( ch ) 
	    && cmd_table[cmd].level)
	{
	    sprintf( buf, "%-12s", cmd_table[cmd].name );
	    send_to_char( buf, ch );
	    if ( ++col % 6 == 0 )
		send_to_char( "\n\r", ch );
	}
    }
 
    if ( col % 6 != 0 )
	send_to_char( "\n\r", ch );
    return;
}