daleken/
daleken/data/notes/
daleken/data/player/
daleken/data/system/poses/
daleken/doc/Homepage/images/
daleken/log/
/*___________________________________________________________________________*
   )()(			  DalekenMUD 1.12 (C) 2000			)()(
   `]['		       by Martin Thomson, Lee Brooks,			`]['
    ||		       Ken Herbert and David Jacques			 ||
    || ----------------------------------------------------------------- ||
    || Envy Diku Mud improvements copyright (C) 1994 by Michael Quan,	 ||
    || David Love, Guilherme 'Willie' Arnold, and Mitchell Tse.		 ||
    || Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael	 ||
    || Chastain, Michael Quan, and Mitchell Tse.			 ||
    || Original Diku Mud copyright (C) 1990, 1991			 ||
    || by Sebastian Hammer, Michael Seifert, Hans Henrik St{rfeldt,	 ||
    || Tom Madsen, and Katja Nyboe.					 ||
    || ----------------------------------------------------------------- ||
    || Any use of this software must follow the licenses of the		 ||
    || creators.  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.					 ||
    || ----------------------------------------------------------------- ||
    ||                            act_wiz.c                              ||
    || Immortal commands.                                                ||
 *_/<>\_________________________________________________________________/<>\_*/


#if defined( WIN32 )
# include <process.h>
#else
# include <sys/stat.h>
# include <unistd.h>
# include <fcntl.h>
# include <errno.h>
#endif

#include "mud.h"
#include "olc.h"
#include "event.h"

int battle_min, battle_max;
BAN_DATA	*ban_list;


/* Special atoi thingy, allows functions to be used in place of
 * integers, destructive to the string so be careful not to reuse the
 * string.
 */
int atoi_functions( char *str )
{
    char *p;
    char *arg;
    int i;

    if( is_number( str ) )
	return atoi( str );

    p = strchr( str, '(' );
    if( !p )			/* not a function */
    {
	return atoi_special( str );
    }
    *p++ = '\0';
    arg = p;
    p = strchr( p, ')' );
    if( !p )
	return -1;
    *p = '\0';

    while( isspace( *str ) )
	str++;
    if( !str_cmp( str, "strlen" ) )
	return strlen( arg );
    if( !str_cmp( str, "speclookup" ) )
	return spec_lookup( arg );
    if( !str_cmp( str, "slookup" ) )
	return skill_lookup( arg );
    if( !str_cmp( str, "race" ) )
	return race_lookup( arg );

    for( i = 0; bit_table[i].structure; ++i )
    {
	if( !str_cmp( str, bit_table[i].command ) )
	    return flag_value( NULL, bit_table[i].structure, arg );
    }
    if( !str_cmp( str, "day" ) )
    {
	for( i = 0; day_name[i] != NULL; ++i )
	{
	    if( !str_cmp( day_name[i], arg ) )
		return i;
	}
    }
    if( !str_cmp( str, "month" ) )
    {
	for( i = 0; month_name[i] != NULL; ++i )
	{
	    if( !str_cmp( month_name[i], arg ) )
		return i;
	}
    }
    return -1;
}


/*
 * Conversion of Immortal powers to Immortal skills done by Thelonius
 */
void do_wizhelp( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char buf[MAX_STRING_LENGTH];
    char buf1[MAX_STRING_LENGTH];
    int cmd;
    int col;

    rch = get_char( ch );

    if( !authorized( rch, "wizhelp" ) )
	return;

    buf1[0] = '\0';
    col = 0;

    for( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
    {
	if( cmd_table[cmd].level < LEVEL_HERO
	    || str_infix( cmd_table[cmd].name, rch->pcdata->immskll ) )
	    continue;

	sprintf( buf, "%-11s", cmd_table[cmd].name );
	strcat( buf1, buf );
	if( ++col % 7 == 0 )
	    strcat( buf1, "\n\r" );
    }

    if( col % 7 != 0 )
	strcat( buf1, "\n\r" );
    send_to_char( buf1, ch );
    return;
}


void do_immname( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch, *victim;
    char arg[MAX_INPUT_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "immname" ) )
	return;

    argument = one_argument( argument, arg );
    if( ( victim = get_char_world( ch, arg ) )
	&& ( ( !IS_NPC( victim ) && get_trust( victim ) < get_trust( ch ) )
	     || victim == rch ) )
    {
	if( colour_strlen( argument ) > 12 )
	{
	    send_to_char( "That might be a little too long.\n\r", ch );
	    return;
	}

	if( !str_cmp( argument, "clear" )
	    || !str_cmp( argument, "reset" )
	    || !str_cmp( argument, "none" ) )
	{
	    free_string( victim->pcdata->immname );
	    victim->pcdata->immname = &str_empty[0];
	    send_to_char( "Immname cleared.\n\r", ch );
	    return;
	}
	else if( argument[0] != '\0' )
	{
	    free_string( victim->pcdata->immname );
	    victim->pcdata->immname = str_dup( argument );
	}

	act( "$O immname is set to:", ch, NULL, victim, TO_CHAR );
	charprintf( ch, "   %s.\n\r",
		    ( victim->pcdata->immname
		      && victim->pcdata->immname[0] != '\0' )
		    ? victim->pcdata->immname : "Nothing" );
    }
    else
    {
	send_to_char( "That person can't get an immname.\n\r", ch );
    }
    return;
}


void do_bamfin( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char mesg[MAX_INPUT_LENGTH];
    const char *punct;

    rch = get_char( ch );

    if( IS_NPC( ch ) || !authorized( rch, "bamfin" ) )
	return;

    if( longstring( ch, argument ) )
	return;

    if( !str_cmp( argument, "clear" )
	|| !str_cmp( argument, "reset" )
	|| !str_cmp( argument, "none" ) )
    {
	free_string( ch->pcdata->bamfin );
	ch->pcdata->bamfin = &str_empty[0];
    }
    else if( argument[0] != '\0' )
    {
	free_string( ch->pcdata->bamfin );
	ch->pcdata->bamfin = str_dup( argument );
    }

    if( ch->pcdata && ch->pcdata->bamfin[0] != '\0' )
	strcpy( mesg, ch->pcdata->bamfin );
    else
	strcpy( mesg, "appears in a swirling mist" );
    punct = mesg + strlen( mesg ) - 1;
    if( isalnum( *punct ) || isspace( *punct ) )
	punct = ".";
    else
	punct = "";
    send_to_char( "Your bamfin is now set as:\n\r", ch );
    charprintf( ch, "   %s %s%s\n\r", ch->name, mesg, punct );
    return;
}


void do_bamfout( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char mesg[MAX_INPUT_LENGTH];
    const char *punct;

    rch = get_char( ch );

    if( !authorized( rch, "bamfout" ) )
	return;

    if( !IS_NPC( ch ) )
    {
	if( longstring( ch, argument ) )
	    return;

	if( !str_cmp( argument, "clear" )
	    || !str_cmp( argument, "reset" )
	    || !str_cmp( argument, "none" ) )
	{
	    free_string( ch->pcdata->bamfout );
	    ch->pcdata->bamfout = &str_empty[0];
	}
	else if( argument[0] != '\0' )
	{
	    free_string( ch->pcdata->bamfout );
	    ch->pcdata->bamfout = str_dup( argument );
	}

	if( ch->pcdata && ch->pcdata->bamfout[0] != '\0' )
	    strcpy( mesg, ch->pcdata->bamfout );
	else
	    strcpy( mesg, "leaves in a swirling mist" );
	punct = mesg + strlen( mesg ) - 1;
	if( isalnum( *punct ) || isspace( *punct ) )
	    punct = ".";
	else
	    punct = "";
	send_to_char( "Your bamfout is now set as:\n\r", ch );
	charprintf( ch, "   %s %s%s\n\r", ch->name, mesg, punct );
    }
    return;
}


void do_deny( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;

    rch = get_char( ch );

    if( !authorized( rch, "deny" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Deny whom?\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "You failed.\n\r", ch );
	return;
    }

    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s has denied %s!",
	     ch->name, victim->name );
    xSET_BIT( victim->act, PLR_DENY );
    send_to_char( "You are denied access!\n\r", victim );
    send_to_char( "OK.\n\r", ch );
    if( victim->level < 2 )
	victim->level = 2;
    do_quit( victim, "" );

    return;
}


void do_disconnect( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim = NULL;
    DESCRIPTOR_DATA *d;
    unsigned int desc_num = 0;

    rch = get_char( ch );

    if( !authorized( rch, "disconnect" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Disconnect whom?\n\r", ch );
	return;
    }

    if( is_number( argument ) )
    {
	desc_num = atoi( argument );
    }

    if( desc_num <= 0 )
    {
	if( !( victim = get_char_world( ch, argument ) ) )
	{
	    send_to_char( "They aren't here.\n\r", ch );
	    return;
	}

	if( !victim->desc )
	{
	    act( "$N doesn't have a descriptor.", ch, NULL, victim, TO_CHAR );
	    return;
	}
    }

    for( d = descriptor_list; d; d = d->next )
    {
	if( d->descriptor == desc_num || ( victim && d == victim->desc ) )
	{
	    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s closing link to %s.",
		     ch->name, CH( d ) ? CH( d )->name : "*Anonymous*" );
	    close_socket( d );
	    send_to_char( "Ok.\n\r", ch );
	    return;
	}
    }

    if( desc_num > 0 )
    {
	send_to_char( "No-one has that descriptor.\n\r", ch );
    }
    else
    {
	bug( "Do_disconnect: desc not found." );
	send_to_char( "Descriptor not found!\n\r", ch );
    }
    return;
}


void do_pardon( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;

    rch = get_char( ch );

    if( !authorized( rch, "pardon" ) )
	return;


    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax: pardon <character>.\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( xIS_SET( victim->act, PLR_OUTLAW ) )
    {
	xREMOVE_BIT( victim->act, PLR_OUTLAW );
	send_to_char( "OUTLAW flag removed.\n\r", ch );
	send_to_char( "You are no longer an OUTLAW.\n\r", victim );
	return;
    }

    send_to_char( "Syntax: pardon <character>.\n\r", ch );
    return;
}


void do_echo( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char arg[MAX_INPUT_LENGTH + 2];

    rch = get_char( ch );

    if( !authorized( rch, "echo" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Echo what?\n\r", ch );
	return;
    }

    strcpy( arg, argument );
    strcat( arg, "\n\r" );
    send_to_all_char( arg );

    return;
}


void do_recho( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    DESCRIPTOR_DATA *d;

    rch = get_char( ch );

    if( !authorized( rch, "recho" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Recho what?\n\r", ch );
	return;
    }

    for( d = descriptor_list; d; d = d->next )
    {
	if( !IS_SET( d->interpreter->flags, INTERPRETER_NOMESSAGE )
	    && d->character->in_room == ch->in_room )
	{
	    send_to_char( argument, d->character );
	    send_to_char( "\n\r", d->character );
	}
    }

    return;
}


ROOM_INDEX_DATA *find_location( CHAR_DATA *ch, const char *arg )
{
    OBJ_DATA *obj;
    CHAR_DATA *victim;

    if( is_number( arg ) )
	return get_room_index( atoi( arg ) );

    if( ( victim = get_char_world( ch, arg ) ) )
	return victim->in_room;

    if( ( obj = get_obj_world( ch, arg ) ) )
	return obj->in_room;

    return NULL;
}


void do_transfer( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    DESCRIPTOR_DATA *d;
    ROOM_INDEX_DATA *location;
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "transfer" ) )
	return;

    argument = one_argument( argument, arg1 );
    one_argument( argument, arg2 );

    if( arg1[0] == '\0' )
    {
	send_to_char( "Transfer whom (and where)?\n\r", ch );
	return;
    }

    if( !str_cmp( arg1, "all" ) )
    {
	for( d = descriptor_list; d; d = d->next )
	{
	    if( !IS_SET( d->interpreter->flags, INTERPRETER_SAFE )
		&& d->character != ch && d->character->in_room
		&& can_see( ch, d->character ) )
	    {
		char buf[MAX_STRING_LENGTH];

		sprintf( buf, "%s %s", d->character->name, arg2 );
		do_transfer( ch, buf );
	    }
	}
	return;
    }

    /*
     * Thanks to Grodyn for the optional location parameter.
     */
    if( arg2[0] == '\0' )
    {
	location = ch->in_room;
    }
    else
    {
	if( !( location = find_location( ch, arg2 ) ) )
	{
	    send_to_char( "No such location.\n\r", ch );
	    return;
	}

	if( room_is_private( location ) )
	{
	    send_to_char( "That room is private right now.\n\r", ch );
	    return;
	}
    }

    if( !( victim = get_char_world( ch, arg1 ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( !victim->in_room )
    {
	send_to_char( "They are in limbo.\n\r", ch );
	return;
    }

    if( victim->fighting )
	stop_fighting( victim, TRUE );
    act( "$n disappears in a mushroom cloud.", victim, NULL, NULL, TO_ROOM );
    char_from_room( victim );
    char_to_room( victim, location );
    act( "$n arrives from a puff of smoke.", victim, NULL, NULL, TO_ROOM );
    if( ch != victim )
	act( "$n has transferred you.", ch, NULL, victim, TO_VICT );
    do_look( victim, AUTOLOOK );
    send_to_char( "Ok.\n\r", ch );
}


void do_at( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *wch;
    ROOM_INDEX_DATA *location;
    ROOM_INDEX_DATA *original;
    OBJ_DATA *orig_on;
    char arg[MAX_INPUT_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "at" ) )
	return;

    argument = one_argument( argument, arg );

    if( arg[0] == '\0' || argument[0] == '\0' )
    {
	send_to_char( "At where what?\n\r", ch );
	return;
    }

    if( !( location = find_location( ch, arg ) ) )
    {
	send_to_char( "No such location.\n\r", ch );
	return;
    }

    if( room_is_private( location ) )
    {
	send_to_char( "That room is private right now.\n\r", ch );
	return;
    }

    original = ch->in_room;
    orig_on = ch->on;
    char_from_room( ch );
    char_to_room( ch, location );
    interpret( ch, argument );

    /*
     * See if 'ch' still exists before continuing!
     * Handles 'at XXXX quit' case.
     */
    for( wch = char_list; wch; wch = wch->next )
    {
	if( wch == ch )
	{
	    char_from_room( ch );
	    char_to_room( ch, original );
	    ch->on = orig_on;
	    break;
	}
    }

    return;
}


void do_goto( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    ROOM_INDEX_DATA *location;
    char mesg[MAX_INPUT_LENGTH];
    const char *punct;

    rch = get_char( ch );

    if( !authorized( rch, "goto" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Goto where?\n\r", ch );
	return;
    }

    if( !( location = find_location( ch, argument ) ) )
    {
	send_to_char( "No such location.\n\r", ch );
	return;
    }

    if( get_trust( ch ) < L_APP && !IS_BUILDER( ch, location->area ) )
    {
	send_to_char( "You can't go to that area.\n\r", ch );
	return;
    }

    if( room_is_private( location ) )
    {
	send_to_char( "That room is private right now.\n\r", ch );
	return;
    }

    if( ch->fighting )
	stop_fighting( ch, TRUE );
    if( !xIS_SET( ch->act, PLR_WIZINVIS ) )
    {
	if( ch->pcdata && ch->pcdata->bamfout[0] != '\0' )
	    strcpy( mesg, ch->pcdata->bamfout );
	else
	    strcpy( mesg, "leaves in a swirling mist" );
	punct = mesg + strlen( mesg ) - 1;
	if( isalnum( *punct ) || isspace( *punct ) )
	    punct = ".";
	else
	    punct = "";
	act( "$n $t$T", ch, mesg, punct, TO_ROOM );
    }

    char_from_room( ch );
    char_to_room( ch, location );

    if( !xIS_SET( ch->act, PLR_WIZINVIS ) )
    {
	if( ch->pcdata && ch->pcdata->bamfin[0] != '\0' )
	    strcpy( mesg, ch->pcdata->bamfin );
	else
	    strcpy( mesg, "appears in a swirling mist" );
	punct = mesg + strlen( mesg ) - 1;
	if( isalnum( *punct ) || isspace( *punct ) )
	    punct = ".";
	else
	    punct = "";
	act( "$n $t$T", ch, mesg, punct, TO_ROOM );
    }

    do_look( ch, AUTOLOOK );
    return;
}


void do_rstat( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    ROOM_INDEX_DATA *location;

    rch = get_char( ch );

    if( !authorized( rch, "rstat" ) )
	return;

    location = ( argument[0] == '\0' ) ? ch->in_room
	: find_location( ch, argument );
    if( !location )
    {
	send_to_char( "No such location.\n\r", ch );
	return;
    }

    if( ch->in_room != location && room_is_private( location ) )
    {
	send_to_char( "That room is private right now.\n\r", ch );
	return;
    }

    show_room( ch, location );
    return;
}


void do_ostat( CHAR_DATA *ch, const char *argument )
{
    OBJ_DATA *obj;
    CHAR_DATA *rch;
    AFFECT_DATA *paf;
    BUFFER *buf;
    char buf1[MAX_STRING_LENGTH];
    char *p;
    int t1, t2;

    rch = get_char( ch );

    if( !authorized( rch, "ostat" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Ostat what?\n\r", ch );
	return;
    }

    if( !( obj = get_obj_world( ch, argument ) ) )
    {
	send_to_char( "Nothing like that in hell, earth, or heaven.\n\r", ch );
	return;
    }

    buf = buffer_new( MAX_STRING_LENGTH );
    bprintf( buf, "&b[&w%6.6d&b]&g Name: &w%s&g.&n\n\r",
	     obj->unique_key, obj->name );

    bprintf( buf, "&gShort description:&w %s&n&g.&n\n\r"
	     "&gLong description: &w%s&n\n\r",
	     obj->short_descr, obj->description );
    while( ( p = strstr( buf->data, "&x" ) ) )
	*( p + 1 ) = 'w';

    if( obj->action && *obj->action )
	bprintf( buf, "&gAction description:&n %s", obj->action );
    buffer_strcat( buf, LINE_SEPARATOR );

    bprintf( buf, "&gVnum:          &b[&r%5d&b]&g Level:   &c%6d"
	     "&g Cost: &y%s&n\n\r",
	     obj->pIndexData->vnum, obj->level,
	     int_to_str_special( obj->cost ) );

    if( ( t1 = get_time_left( obj->events, evn_obj_decay ) ) < 0 )
	t1 = -1;
    else
	t1 /= PULSE_PER_SECOND;
    if( ( t2 = get_time_left( obj->events, evn_imp_grab ) ) < 0 )
	t2 = -1;
    else
	t2 /= PULSE_PER_SECOND;

    bprintf( buf, "&gType: &c%-16s&g Timer: &c%4d&b:&c%3d"
	     "&g Weight: &c%d&g/&c%d&n\n\r",
	     flag_string( type_flags, &obj->item_type ),
	     t1, t2, obj->weight, get_obj_weight( obj ) );

    bprintf( buf, "&gCarried By: &y%-10.10s&g In Room &b[&r%5d&b]"
	     "&g In Object: &g%s&n\n\r",
	     !obj->carried_by ? "(none)" : obj->carried_by->name,
	     !obj->in_room ? 0 : obj->in_room->vnum,
	     !obj->in_obj ? "(none)" : obj->in_obj->short_descr );

    bprintf( buf, "&gCondition: &c%8d.%1.1d%%&g &gMaterial:  &c%s&n\n\r",
	     obj->condition / 10, obj->condition % 10,
	     flag_string( material_flags, &obj->pIndexData->material ) );

    bprintf( buf, "&gWear Loc: &c%12s",
	     flag_string( wear_loc_flags, &obj->wear_loc ) );
    bprintf( buf, "&g Wear Flags: &c%s&n\n\r",
	     flag_string( wear_flags, &obj->wear_flags ) );

    bprintf( buf, "&gExtra Flags: &c%s&n\n\r",
	     flag_string( extra_flags, &obj->extra_flags ) );

    if( obj->extra_descr || obj->pIndexData->extra_descr )
    {
	EXTRA_DESCR_DATA *ed;

	buffer_strcat( buf, "&gExtra description keywords: &c'" );

	for( ed = obj->extra_descr; ed; ed = ed->next )
	{
	    buffer_strcat( buf, ed->keyword );
	    if( ed->next )
		buffer_strcat( buf, " " );
	}

	for( ed = obj->pIndexData->extra_descr; ed; ed = ed->next )
	{
	    buffer_strcat( buf, ed->keyword );
	    if( ed->next )
		buffer_strcat( buf, " " );
	}

	buffer_strcat( buf, "'&g.&n\n\r" );
    }

    bprintf( buf, "&gValues: &c%d %d %d %d&n\n\r",
	     obj->value[0], obj->value[1],
	     obj->value[2], obj->value[3] );

    show_obj_values( obj->item_type, obj->value, buf );

    buffer_strcat( buf, LINE_SEPARATOR );
    for( paf = obj->affected; paf; paf = paf->next )
    {
	buffer_strcat( buf, show_affect( buf1, paf, TRUE, TRUE ) );
    }
    for( paf = obj->pIndexData->affected; paf; paf = paf->next )
    {
	buffer_strcat( buf, show_affect( buf1, paf, TRUE, TRUE ) );
    }

    send_to_char( buf->data, ch );
    buffer_free( buf );
    return;
}


/*
 * sstat by Garion
 * Modified for Daleken.
 */
void do_sstat( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    BUFFER *outbuf = buffer_new( MAX_STRING_LENGTH );

    int sn;
    int col = 0;

    rch = get_char( ch );
    if( !authorized( rch, "sstat" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Sstat whom\n\r?", ch );
	return;
    }

    if( ( victim = get_char_world( ch, argument ) ) == NULL )
    {
	send_to_char( "That person isn't logged on.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    bprintf( outbuf, "&cSkill/Spell Name	     Cost  %   | ...\n\r" );
    buffer_strcat( outbuf, LINE_SEPARATOR );
    for( sn = 1; sn < MAX_SKILL; sn++ )
    {
	if( !skill_table[sn].name )
	    break;
	if( victim->pcdata->learned[sn] > 0 )
	{
	    bprintf( outbuf, "&g%-28.28s &y%4d %3d%%",
		     skill_table[sn].name,
		     total_mana_cost( victim, sn ),
		     victim->pcdata->learned[sn] );
	    if( ++col % 2 == 0 )
		buffer_strcat( outbuf, "&n\n\r" );
	    else
		buffer_strcat( outbuf, " &n| " );
	}
    }

    if( col % 2 != 0 )
	buffer_strcat( outbuf, "&n\n\r" );

    buffer_strcat( outbuf, LINE_SEPARATOR );
    bprintf( outbuf, "&g%s has &c%d&g practice sessions left.&n\n\r",
	     victim->name, victim->practice );
    send_to_char( outbuf->data, ch );
    buffer_free( outbuf );
}


void do_mstat( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    AFFECT_DATA *paf;
    BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
    char tmp[MAX_STRING_LENGTH];
    char tmp2[MAX_STRING_LENGTH];
    int cc;

    rch = get_char( ch );

    if( !authorized( rch, "mstat" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Mstat whom?\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    bprintf( buf, "&b[&w%6.6d&b]&g &g%s: &c%s&g, &ma%s %s %s&n\n\r",
	     victim->unique_key,
	     IS_NPC( victim ) ? "Mobile" : "Player",
	     victim->name,
	     isvowel( *race_table[victim->race].name ) ? "n" : "",
	     race_table[victim->race].name,
	     victim->class >= 0 ? class_table[victim->class].name : "Mob" );
    bprintf( buf, "&gShort descr:     &w%s&n\n\r",
	     ( victim->short_descr && *victim->short_descr )
	     ? victim->short_descr : "(none)" );
    bprintf( buf, "&gLong descr:      &w%s&n",
	     ( victim->long_descr && *victim->long_descr )
	     ? victim->long_descr : "(none)\n\r" );
    bprintf( buf, "&gVnum: &b[&r%10d&b]&g   Number: &c%5d"
	     "&g   Room:  &b[&r%4d&b]&n\n\r",
	     IS_NPC( victim ) ? victim->pIndexData->vnum : 0,
	     IS_NPC( victim ) ? victim->pIndexData->count : 1,
	     victim->in_room ? victim->in_room->vnum : 0 );
    bprintf( buf, "&gLevel: &c%5d&g(&c%4d&g)"
	     "   Tnl: &c%4d.%2.2d&g/&c%4d&n\n\r",
	     victim->level, victim->sublevel,
	     victim->exp / 100, victim->exp % 100, get_tnl( victim ) / 100 );
    bprintf( buf, "&gAge:    &c%3d&g          Played: &c%-7d"
	     "&g Timer:    &c%d&n\n\r",
	     get_age( victim ), (int)victim->played,
	     victim->pcdata ? victim->pcdata->timer : -1 );
    buffer_strcat( buf, LINE_SEPARATOR );
    bprintf( buf, "&bStr: &c%7d&b(&c%4d&b)&g   Hitroll: &c%4d"
	     "&g   Hits:     &c%d&b/&c%d&n\n\r",
	     IS_NPC( victim ) ? 15 + race_table[victim->race].str_mod
	     : victim->pcdata->perm_str,
	     get_curr_str( victim ),
	     get_hitroll( victim ),
	     victim->hit, victim->max_hit );
    bprintf( buf, "&bInt: &c%7d&b(&c%4d&b)&g   Damroll: &c%4d"
	     "&g   Mana:     &c%d&b/&c%d&n\n\r",
	     IS_NPC( victim ) ? 15 + race_table[victim->race].int_mod
	     : victim->pcdata->perm_int,
	     get_curr_int( victim ),
	     get_damroll( victim ),
	     total_mana( victim->mana ), total_mana( victim->max_mana ) );
    bprintf( buf, "&bWis: &c%7d&b(&c%4d&b)&g   Speed: &c%6d"
	     "&g   Move:     &c%d&b/&c%d&n\n\r",
	     IS_NPC( victim ) ? 15 + race_table[victim->race].wis_mod
	     : victim->pcdata->perm_wis,
	     get_curr_wis( victim ),
	     get_speed( victim ),
	     victim->move, victim->max_move );
    bprintf( buf, "&bDex: &c%7d&b(&c%4d&b)&g   AC: &c%9d"
	     "&g   Wimpy:    &c%d&n\n\r",
	     IS_NPC( victim ) ? 15 + race_table[victim->race].dex_mod
	     : victim->pcdata->perm_dex,
	     get_curr_dex( victim ),
	     GET_AC( victim ), victim->wimpy );
    bprintf( buf, "&bCon: &c%7d&b(&c%4d&b)&g   Save: &c%7d"
	     "&g   Gold:     &y%d&r/&y%d&n\n\r",
	     IS_NPC( victim ) ? 15 + race_table[victim->race].con_mod
	     : victim->pcdata->perm_con,
	     get_curr_con( victim ),
	     victim->saving_throw, victim->gold,
	     IS_NPC( victim ) ? 0 : victim->pcdata->banked );
    bprintf( buf, "&rResil: &y%5d&r(&y%4d&r)&g   &gAlign: &c%6d"
	     "&g   Pracs:    &c%d&n\n\r",
	     race_table[victim->race].resil, get_curr_resil( victim ),
	     victim->alignment, victim->practice );
    cc = 0;
    bprintf( buf, "%s%-8s %3d(%4d) %9d/%5d&g   Carried:  &c%-3d&b/&c%d&n\n\r",
	     magic_colour[cc], magic_name[cc],
	     IS_NPC( victim ) ? 2 + race_table[victim->race].mana_gain[cc]
	     : victim->pcdata->perm_magic[cc], get_magic( victim, cc ),
	     victim->mana[cc], victim->max_mana[cc],
	     victim->carry_number, can_carry_n( victim ) );
    ++cc;
    bprintf( buf, "%s%-8s %3d(%4d) %9d/%5d&g   Weight:   &c%-3d&b/&c%d&n\n\r",
	     magic_colour[cc], magic_name[cc],
	     IS_NPC( victim ) ? 2 + race_table[victim->race].mana_gain[cc]
	     : victim->pcdata->perm_magic[cc], get_magic( victim, cc ),
	     victim->mana[cc], victim->max_mana[cc],
	     victim->carry_weight, can_carry_w( victim ) );
    ++cc;
    bprintf( buf, "%s%-8s %3d(%4d) %9d/%5d&g   Position: &c%d&n\n\r",
	     magic_colour[cc], magic_name[cc],
	     IS_NPC( victim ) ? 2 + race_table[victim->race].mana_gain[cc]
	     : victim->pcdata->perm_magic[cc], get_magic( victim, cc ),
	     victim->mana[cc], victim->max_mana[cc],
	     victim->position );
    ++cc;
    bprintf( buf, "%s%-8s %3d(%4d) %9d/%5d&g   Sex:      &c%s&n\n\r",
	     magic_colour[cc], magic_name[cc],
	     IS_NPC( victim ) ? 2 + race_table[victim->race].mana_gain[cc]
	     : victim->pcdata->perm_magic[cc], get_magic( victim, cc ),
	     victim->mana[cc], victim->max_mana[cc],
	     flag_string( sex_flags, &victim->sex ) );
    ++cc;
    bprintf( buf, "%s%-8s %3d(%4d) %9d/%5d&r   Size: &y%4d&r(&y%4d&r)&n\n\r",
	     magic_colour[cc], magic_name[cc],
	     IS_NPC( victim ) ? 2 + race_table[victim->race].mana_gain[cc]
	     : victim->pcdata->perm_magic[cc], get_magic( victim, cc ),
	     victim->mana[cc], victim->max_mana[cc],
	     race_table[victim->race].size, get_size( victim ) );
    bprintf( buf, "&gTotal   ----(----) %9d/%5d"
	     "&r   Temp: &y%4d&r(&y%4d&r)&n\n\r",
	     total_mana( victim->mana ), total_mana( victim->max_mana ),
	     race_table[victim->race].body_temp + 37,
	     get_curr_temp( victim ) + 37 );

    if( !IS_NPC( victim ) )
	bprintf( buf, "&mFull:  &c%6d&m        Thirst: &c%5d"
		 "&m   Drunk:   &c%d&n\n\r",
		 ( victim->pcdata->condition[COND_FULL] + 5 ) / 10,
		 ( victim->pcdata->condition[COND_THIRST] + 5 ) / 10,
		 ( victim->pcdata->condition[COND_DRUNK] + 5 ) / 10 );


    buffer_strcat( buf, LINE_SEPARATOR );
    cc = 0;
    if( victim->on )
    {
	bprintf( buf, "&rOn: &y%s", victim->on->short_descr );
	cc = 1;
    }
    if( victim->fighting )
    {
	bprintf( buf, "&rFighting: &y%s ", victim->fighting->name );
	cc = 1;
    }
    if( victim->leader )
    {
	bprintf( buf, "&rLeader: &y%s ", victim->leader->name );
	cc = 1;
    }
    if( victim->master )
    {
	bprintf( buf, "&rMaster: &y%s", victim->master->name );
	cc = 1;
    }
    if( victim->tracking )
    {
	bprintf( buf, "&rHunting: &y%s", victim->tracking->name );
	cc = 1;
    }
    if( victim->fearing )
    {
	bprintf( buf, "&rFearing: &y%s", victim->fearing->name );
	cc = 1;
    }
    if( cc )
	buffer_strcat( buf, "&n\n\r" );
    if( is_clan( victim ) )
	bprintf( buf, "&rClan: &y%s &rRank: &y%s&n\n\r",
		 victim->pcdata->clan->name,
		 rank_name( victim->pcdata->clan_rank,
			    victim->pcdata->clan->clan_type ) );
    if( victim->pcdata && victim->pcdata->religion )
	bprintf( buf, "&bReligion: &c%s&n\n\r",
		 victim->pcdata->religion->name );
    sprintf( tmp, "&gAct:           &b[&c%s&b]&n\n\r",
	     IS_NPC( victim )
	     ? flag_string( act_flags, victim->act )
	     : flag_string( pc_act_flags, victim->act ) );
    buffer_strcat( buf, multi_line( tmp2, tmp, 79, 16 ) );
    if( IS_NPC( victim ) && victim->spec_fun > 0 )
	bprintf( buf, "&gSpec:          &b[&c%s&b]&n\n\r",
		 spec_table[victim->spec_fun].spec_name );
    sprintf( tmp, "&gBody Parts:    &b[&c%s&b]&n\n\r",
	     flag_string( body_part_flags, &victim->body_parts ) );
    buffer_strcat( buf, multi_line( tmp2, tmp, 79, 16 ) );
    sprintf( tmp, "&gAffected Bits: &b[&c%s&b]&n\n\r",
	     flag_string( affect_flags, victim->affected_by ) );
    buffer_strcat( buf, multi_line( tmp2, tmp, 79, 16 ) );
    for( paf = victim->affected; paf; paf = paf->next )
    {
	if( paf->deleted
	    || IS_SET( skill_table[paf->type].skill_type, SKILL_TYPE_ENCHANTMENT ) )
	    continue;
	buffer_strcat( buf, show_affect( tmp, paf, TRUE, TRUE ) );
    }
    send_to_char( buf->data, ch );
    buffer_free( buf );
    return;
}


void do_mfind( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    MOB_INDEX_DATA *pMobIndex;
    BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
    int vnum;
    int nMatch;
    bool fAll;
    bool found;

    rch = get_char( ch );

    if( !authorized( rch, "mfind" ) )
    {
	buffer_free( buf );
	return;
    }

    if( argument[0] == '\0' )
    {
	send_to_char( "Mfind whom?\n\r", ch );
	buffer_free( buf );
	return;
    }
    else if( strlen( argument ) < 2 )
    {
	send_to_char( "That name is too short, try a longer one.\n\r", ch );
	buffer_free( buf );
	return;
    }

    fAll = !str_cmp( argument, "all" );
    found = FALSE;
    nMatch = 0;

    /*
     * Yeah, so iterating over all vnum's takes 10,000 loops.
     * Get_mob_index is fast, and I don't feel like threading another link.
     * Do you?
     * -- Furey
     */
    for( vnum = 0; nMatch < top_mob_index && vnum < top_vnum_mob; vnum++ )
    {
	if( ( pMobIndex = get_mob_index( vnum ) ) )
	{
	    nMatch++;
	    if( fAll || is_name( argument, pMobIndex->name ) )
	    {
		found = TRUE;
		bprintf( buf, "&b[&r%5d&b] &g%s&n\n\r",
			 pMobIndex->vnum, capitalize( pMobIndex->short_descr ) );
	    }
	}
    }

    if( !found )
	send_to_char( "Nothing like that in hell, earth, or heaven.\n\r", ch );
    else
	send_to_char( buf->data, ch );
    buffer_free( buf );
    return;
}


void do_ofind( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    OBJ_INDEX_DATA *pObjIndex;
    BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
    char arg[MAX_INPUT_LENGTH];
    int vnum;
    int nMatch;
    bool fAll;
    bool found;

    rch = get_char( ch );

    if( !authorized( rch, "ofind" ) )
    {
	buffer_free( buf );
	return;
    }

    if( argument[0] == '\0' )
    {
	send_to_char( "Ofind what?\n\r", ch );
	buffer_free( buf );
	return;
    }
    else if( strlen( argument ) < 2 )
    {
	send_to_char( "That name is too short, try a longer one.\n\r", ch );
	buffer_free( buf );
	return;
    }

    fAll = !str_cmp( arg, "all" );
    found = FALSE;
    nMatch = 0;

    for( vnum = 0; nMatch < top_obj_index && vnum < top_vnum_obj; vnum++ )
    {
	if( ( pObjIndex = get_obj_index( vnum ) ) )
	{
	    nMatch++;
	    if( fAll || is_name( argument, pObjIndex->name ) )
	    {
		found = TRUE;
		bprintf( buf, "&b[&r%5d&b] &g%s&n\n\r",
			 pObjIndex->vnum, capitalize( pObjIndex->short_descr ) );
	    }
	}
    }

    if( !found )
	send_to_char( "Nothing like that in hell, earth, or heaven.\n\r", ch );
    else
	send_to_char( buf->data, ch );
    buffer_free( buf );
    return;
}


void do_mwhere( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    BUFFER *buf;
    char arg[MAX_INPUT_LENGTH];
    int count;
    int mob_count = 0;
    bool found;

    rch = get_char( ch );

    if( !authorized( rch, "mwhere" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Mwhere whom?\n\r", ch );
	return;
    }
    else if( strlen( argument ) < 3 )
    {
	send_to_char( "That name is too short, try a longer one.\n\r", ch );
	return;
    }

    buf = buffer_new( MAX_STRING_LENGTH );
    count = number_argument( argument, arg );
    found = FALSE;
    for( victim = char_list; victim; victim = victim->next )
    {
	if( !IS_NPC( victim ) || !victim->in_room
	    || !is_char_name( victim, arg ) )
	    continue;
	if( ++mob_count > 100 )
	    break;
	if( --count <= 0 )
	{
	    char tmp[MAX_INPUT_LENGTH];

	    found = TRUE;
	    bprintf( buf, "&b[&r%5d&b] &g%s &b[&r%5d&b] &y%s&n\n\r",
		     victim->pIndexData->vnum,
		     colour_strpad( tmp, victim->short_descr, 28 ),
		     victim->in_room->vnum,
		     victim->in_room->name );
	}
    }

    if( !found )
	act( "You didn't find any $T.", ch, NULL, argument, TO_CHAR );
    else
    {
	bprintf( buf, "%d mobiles found.\n\r", mob_count );
	send_to_char( buf->data, ch );
    }
    buffer_free( buf );
    return;
}


void do_reboo( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "reboot" ) )
	return;

    send_to_char( "If you want to REBOOT, spell it out.\n\r", ch );
    return;
}


void do_reboot( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char buf[MAX_STRING_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "reboot" ) )
	return;

    sprintf( buf, "Reboot by %s.", ch->name );
    do_echo( ch, buf );

    end_of_game( );

    merc_down = TRUE;
    return;
}


void do_shutdow( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "shutdown" ) )
	return;

    send_to_char( "If you want to SHUTDOWN, spell it out.\n\r", ch );
    return;
}


void do_shutdown( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char buf[MAX_STRING_LENGTH];
    FILE *fp;

    rch = get_char( ch );

    if( !authorized( rch, "shutdown" ) )
	return;

    sprintf( buf, "Shutdown by %s.", ch->name );
    if( !( fp = open_file( SHUTDOWN_FILE, "a", FALSE ) ) )
    {
	perror( SHUTDOWN_FILE );
	send_to_char( "Could not open the file!\n\r", ch );
    }
    else
    {
	fprintf( fp, buf );
	close_file( fp );
    }

    strcat( buf, "\n\r" );
    do_echo( ch, buf );

    end_of_game( );

    merc_down = TRUE;
    return;
}


void do_snoop( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    DESCRIPTOR_DATA *d;
    char arg[MAX_INPUT_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "snoop" ) )
	return;

    one_argument( argument, arg );

    if( arg[0] == '\0' )
    {
	send_to_char( "Snoop whom?\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, arg ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( !victim->desc )
    {
	send_to_char( "No descriptor to snoop.\n\r", ch );
	return;
    }

    if( victim == ch )
    {
	send_to_char( "Cancelling all snoops.\n\r", ch );
	for( d = descriptor_list; d; d = d->next )
	{
	    if( d->snoop_by == ch->desc )
		d->snoop_by = NULL;
	}
	return;
    }

    if( victim->desc->snoop_by )
    {
	send_to_char( "Busy already.\n\r", ch );
	return;
    }

    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "You failed.\n\r", ch );
	return;
    }

    if( ch->desc )
    {
	for( d = ch->desc->snoop_by; d; d = d->snoop_by )
	{
	    if( d->character == victim || d->original == victim )
	    {
		send_to_char( "No snoop loops.\n\r", ch );
		return;
	    }
	}
    }

    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s snooping %s.",
	     ch->name, victim->name );
    victim->desc->snoop_by = ch->desc;
    send_to_char( "Ok.\n\r", ch );
    return;
}


void do_switch( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;

    rch = get_char( ch );

    if( !authorized( rch, "switch" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Switch into whom?\n\r", ch );
	return;
    }

    if( !ch->desc )
	return;

    if( ch->desc->original )
    {
	send_to_char( "You are already switched.\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( victim == ch )
    {
	send_to_char( "Ok.\n\r", ch );
	return;
    }

    /*
     * Pointed out by Da Pub (What Mud)
     * If taking this out causes crashes I don't know why.
     *
     if( !IS_NPC( victim ) )
     {
     send_to_char( "You cannot switch into a player!\n\r", ch );
     return;
     }
    */

    if( !IS_NPC( victim ) && ch->pcdata->switched )
    {
	send_to_char( "Not switched immortals, they might return.\n\r", ch );
	return;
    }

    if( victim->desc )
    {
	send_to_char( "Character in use.\n\r", ch );
	return;
    }

    ch->pcdata->switched = TRUE;
    ch->desc->character = victim;
    ch->desc->original = ch;
    victim->desc = ch->desc;
    ch->desc = NULL;
    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s switched to %s.",
	     ch->name, victim->name );
    send_to_char( "Ok.\n\r", victim );
    return;
}


void do_return( CHAR_DATA *ch, const char *argument )
{
    if( !ch->desc )
	return;

    if( !ch->desc->original )
    {
	send_to_char( "You aren't switched.\n\r", ch );
	return;
    }

/* Note that we dont check for immortal ability to have return here.
 * We assume we will automatically allow immortals with switch to return.
 * Don't want to have our immortals stuck in a mobile's body do we?  :)
 * -Kahn
 */

    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s returned to their body.",
	    ch->name );
    send_to_char( "You return to your original body.\n\r", ch );
    ch->desc->original->pcdata->switched = FALSE;
    ch->desc->character = ch->desc->original;
    ch->desc->original = NULL;
    ch->desc->character->desc = ch->desc;
    ch->desc = NULL;
    return;
}


void do_mload( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    MOB_INDEX_DATA *pMobIndex;
    char arg[MAX_INPUT_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "mload" ) )
	return;

    one_argument( argument, arg );

    if( arg[0] == '\0' || !is_number( arg ) )
    {
	send_to_char( "Syntax: mload <vnum>.\n\r", ch );
	return;
    }

    if( !( pMobIndex = get_mob_index( atoi( arg ) ) ) )
    {
	send_to_char( "No mob has that vnum.\n\r", ch );
	return;
    }

    victim = create_mobile( pMobIndex );
    char_to_room( victim, ch->in_room );
    wiznetf( ch, WIZ_CREATE, get_trust( ch ), "%s has created mobile %s&g (%d).",
	    ch->name, victim->short_descr, pMobIndex->vnum );
    send_to_char( "Ok.\n\r", ch );
    act( "$n has created $N!", ch, NULL, victim, TO_ROOM );
    return;
}


void do_oload( CHAR_DATA *ch, const char *argument )
{
    OBJ_DATA *obj;
    CHAR_DATA *rch;
    OBJ_INDEX_DATA *pObjIndex;
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    int level;

    rch = get_char( ch );

    if( !authorized( rch, "oload" ) )
	return;

    argument = one_argument( argument, arg1 );
    one_argument( argument, arg2 );

    if( arg1[0] == '\0' || !is_number( arg1 ) )
    {
	send_to_char( "Syntax: oload <vnum> <level>.\n\r", ch );
	return;
    }

    if( arg2[0] == '\0' )
    {
	level = 0;
    }
    else
    {
	/*
	 * New feature from Alander.
	 */
	if( !is_number( arg2 ) )
	{
	    send_to_char( "Syntax: oload <vnum> <level>.\n\r", ch );
	    return;
	}
	level = atoi_special( arg2 );
	if( level < 0 || level > get_trust( ch ) )
	{
	    send_to_char( "Limited to your trust level.\n\r", ch );
	    return;
	}
    }

    if( !( pObjIndex = get_obj_index( atoi( arg1 ) ) ) )
    {
	send_to_char( "No object has that vnum.\n\r", ch );
	return;
    }

    obj = create_object( pObjIndex, level );

    if( CAN_WEAR( obj, ITEM_TAKE ) )
    {
	obj_to_char( obj, ch );
    }
    else
    {
	obj_to_room( obj, ch->in_room );
	strip_events( &obj->events, evn_imp_grab );
	act( "$n has created $p!", ch, obj, NULL, TO_ROOM );
    }
    wiznetf( ch, WIZ_CREATE, get_trust( ch ), "%s has created object %s&g (%d).",
	     ch->name, obj->short_descr, pObjIndex->vnum );
    send_to_char( "Ok.\n\r", ch );
    return;
}


void purge_room( CHAR_DATA *ch, const char *argument )
{
    OBJ_DATA *obj;
    CHAR_DATA *victim;

    if( argument[0] == '\0' || !str_cmp( argument, "all" )
	|| !str_prefix( "all.", argument )
	|| !str_cmp( "mob", argument )
	|| !str_cmp( "obj", argument ) )
    {
	/*
	 * 'purge'
	 */
	OBJ_DATA *obj_next;
	CHAR_DATA *vnext;

	for( victim = ch->in_room->people; victim; victim = vnext )
	{
	    vnext = victim->next_in_room;
	    if( victim->deleted || !str_cmp( "obj", argument ) )
		continue;
	    if( argument[0] != '\0' && argument[3] != '\0'
		&& !is_char_name( victim, &argument[4] ) )
		continue;

	    if( IS_NPC( victim ) && victim != ch )
		extract_char( victim, TRUE );
	}

	for( obj = ch->in_room->contents; obj; obj = obj_next )
	{
	    obj_next = obj->next_content;
	    if( obj->deleted || !str_cmp( "mob", argument ) )
		continue;
	    if( argument[0] != '\0' && argument[3] != '\0'
		&& !is_obj_name( obj, &argument[4] ) )
		continue;

	    if( obj->item_type == ITEM_CORPSE_PC )
		send_to_char( "Make sure of purging pc corpses, "
			      "purge them individually.\n\r", ch );
	    else
		extract_obj( obj );
	}

	send_to_char( "Ok.\n\r", ch );
	if( !IS_NPC( ch ) )
	    act( "$n purges the room!", ch, NULL, NULL, TO_ROOM );
	return;
    }

    if( !( victim = get_char_room( ch, argument ) ) )
    {
	if( ( obj = get_obj_list( ch, argument, ch->in_room->contents ) ) )
	{
	    if( !IS_NPC( ch ) )
		act( "$n purges $p!", ch, obj, NULL, TO_ROOM );
	    send_to_char( "Ok.\n\r", ch );
	    extract_obj( obj );
	}
	else
	{
	    send_to_char( "That isn't here.\n\r", ch );
	}
	return;
    }

    if( !IS_NPC( victim ) )
    {
	send_to_char( "Not on PC's.\n\r", ch );
	return;
    }

    if( !IS_NPC( ch ) )
	act( "$n purges $N.", ch, NULL, victim, TO_NOTVICT );
    send_to_char( "Ok.\n\r", ch );
    extract_char( victim, TRUE );
    return;
}


void do_purge( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "purge" ) )
	return;

    purge_room( ch, argument );
    return;
}


void do_advance( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg1[MAX_INPUT_LENGTH];
    bool sublevel = FALSE;
    int level;
    int iLevel;
    int hp, mana[MAGIC_MAX], move, prac;
    int sn;

    rch = get_char( ch );

    if( !authorized( rch, "advance" ) )
	return;

    argument = one_argument( argument, arg1 );

    if( arg1[0] == '\0' || argument[0] == '\0' )
    {
	send_to_char( "Syntax: advance <char> <level>\n\r", ch );
	return;
    }

    if( !( victim = get_char_room( ch, arg1 ) ) )
    {
	send_to_char( "That player is not here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( victim->sublevel )
    {
	argument = one_argument( argument, arg1 );
	if( argument[0] == '\0' || !is_number( argument )
	    || ( str_cmp( arg1, "level" ) && str_cmp( arg1, "sublevel" ) ) )
	{
	    send_to_char( "For victims that are multiclassing, "
			  "please specify level or sublevel.\n\r", ch );
	    return;
	}
	if( !str_cmp( arg1, "sublevel" ) )
	    sublevel = TRUE;
    }

    if( !is_number( argument ) )
    {
	send_to_char( "Usage: advance <character> [sublevel|level] <level>\n\r",
		      ch );
	return;
    }

    level = atoi( argument );

    if( level <= 0 || level > LEVEL_HERO )
    {
	charprintf( ch, "Advance within range 1 to %d.\n\r", LEVEL_HERO );
	return;
    }
    if( victim->sublevel && ( level > victim->level
			      || ( sublevel && level <= victim->sublevel ) ) )
    {
	send_to_char(
	    "For multiclassing characters, you may only demote them to a\n\r"
	    "lower level, or promote them sublevels.\n\r", ch );
	return;
    }

    /*
     * Lower level:
     *	 Reset to level 1.
     *	 Then raise again.
     *	 Currently, an imp can lower another imp.
     *	 -- Swiftest
     */
    if( !sublevel && level <= victim->level )
    {
	send_to_char( "Lowering a player's level!\n\r", ch );
	send_to_char( "&R**** OOOOHHHHHHHHHH NNNNOOOO ****&n\n\r", victim );
	victim->level = 1;
	victim->sublevel = 0;
	victim->exp = get_tnl( victim );
	victim->max_hit = 20;
	victim->hit = victim->max_hit;
	for( sn = 0; sn < MAGIC_MAX; ++sn )
	{
	    victim->max_mana[sn] = 10 + class_table[victim->class].fMana;
	    victim->mana[sn] = victim->max_mana[sn];
	}
	victim->max_move = 100;
	victim->move = victim->max_move;
	for( sn = 0; sn < MAX_SKILL; sn++ )
	    victim->pcdata->learned[sn] = 0;
	if( get_first_class( victim ) != CLASS_NONE )
	    victim->class = get_first_class( victim );
	for( sn = 0; sn < NUM_MULTI_CLASS; sn++ )
	    victim->pcdata->multi_class[sn] = CLASS_UNKNOWN;
	victim->practice = 300;
	advance_level( victim, TRUE );
	wiznetf( victim, WIZ_LEVELS, get_trust( rch ),
		 "%s has been demoted to level %d by %s",
		 victim->name, level, ch->name );
    }
    else
    {
	send_to_char( "Raising a player's level!\n\r", ch );
	send_to_char( "&B**** OOOOHHHHHHHHHH  YYYYEEEESSS ****&n\n\r",
		      victim );
	wiznetf( victim, WIZ_LEVELS, get_trust( rch ),
		 "%s has been advanced to %slevel %d by %s",
		 victim->name, sublevel ? "sub" : "", level, ch->name );
    }

    hp = victim->max_hit;
    for( sn = 0; sn < MAGIC_MAX; ++sn )
	mana[sn] = victim->max_mana[sn];
    move = victim->max_move;
    prac = victim->practice;
    if( victim->sublevel > 0 )
    {
	for( iLevel = victim->sublevel; iLevel < level; iLevel++ )
	{
	    victim->sublevel += 1;
	    advance_level( victim, TRUE );
	}
    }
    else
    {
	for( iLevel = victim->level; iLevel < level; iLevel++ )
	{
	    victim->level += 1;
	    advance_level( victim, TRUE );
	}
    }
    charprintf( victim, "&GYou raise some levels!!! "
	     "&mYour gain is %d/%dhp %d/%dmv %d/%d practices.\n\r&gMana: ",
	     victim->max_hit - hp, victim->max_hit,
	     victim->max_move - move, victim->max_move,
	     victim->practice - prac, victim->practice );
    for( sn = 0; sn < MAGIC_MAX; ++sn )
	charprintf( victim, "%s%d/%d %s%s", magic_colour[sn],
		    victim->max_mana[sn] - mana[sn],
		    get_max_mana( victim, sn ), magic_name[sn],
		    ( sn < MAGIC_MAX - 1 ) ? ", " : "&g.&n\n\r" );
    victim->trust = 0;
    return;
}


void do_trust( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    int level, max_level;

    rch = get_char( ch );

    if( !authorized( rch, "trust" ) )
	return;

    argument = one_argument( argument, arg1 );
    one_argument( argument, arg2 );

    if( arg1[0] == '\0' || arg2[0] == '\0' || !is_number( arg2 ) )
    {
	send_to_char( "Syntax: trust <char> <level>.\n\r", ch );
	return;
    }

    if( !( victim = get_char_room( ch, arg1 ) ) )
    {
	send_to_char( "That player is not here.\n\r", ch );
	return;
    }

    level = atoi( arg2 );

    max_level = UMIN( MAX_LEVEL, ( get_trust( ch ) - 800 ) * 8 );

    if( level < 1 || level > max_level )
    {
	char buf[MAX_STRING_LENGTH];

	sprintf( buf, "Trust within range 1 to %d.\n\r", max_level );
	send_to_char( buf, ch );
	return;
    }
    sprintf( arg1, "%s has been trusted at level %d by %s", victim->name,
	     level, ch->name );
    wiznet( ch, WIZ_LEVELS, get_trust( rch ), arg1 );

    victim->trust = level;
    return;
}


void do_restore( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg[MAX_INPUT_LENGTH];
    char buf[MAX_INPUT_LENGTH];
    bool parts = FALSE;
    bool mobs = FALSE;
    bool mesg = FALSE;

    rch = get_char( ch );

    if( !authorized( rch, "restore" ) )
	return;

    argument = one_argument( argument, arg );
    if( arg[0] == '\0' )
    {
	send_to_char( "Syntax: restore <char|all> [mobs|parts]\n\r", ch );
	send_to_char( "also: restore <...> [...] message <message>\n\r", ch );
	return;
    }

    while( argument[0] != '\0' )
    {
	argument = one_argument( argument, buf );
	if( !str_cmp( buf, "mobs" ) )
	    mobs = TRUE;
	if( !str_cmp( buf, "parts" ) )
	    parts = TRUE;
	if( !str_cmp( buf, "message" ) || !str_cmp( buf, "mesg" ) )
	{
	    mesg = TRUE;
	    if( argument[0] == '\0' )
	    {
		send_to_char( "You need to put a message here.\n\r", ch );
		return;
	    }
	    break;
	}
    }

    /*
     * Restore All feature coded by Katrina
     */
    if( !str_cmp( arg, "all" ) )
    {
	for( victim = char_list; victim; victim = victim->next )
	{
	    int i;
	    if( victim->deleted )
		continue;
	    if( IS_NPC( victim ) && !mobs )
		continue;
	    victim->hit = victim->max_hit;
	    for( i = 0; i < MAGIC_MAX; ++i )
		victim->mana[i] = victim->max_mana[i];
	    victim->move = victim->max_move;
	    xREMOVE_BIT( victim->affected_by, AFF_BLEEDING );
	    if( parts )
		victim->body_parts = race_table[victim->race].body_parts;
	    if( !IS_NPC( victim ) )
	    {
		victim->pcdata->condition[COND_FULL] =
		    race_table[victim->race].hunger_mod * 10;
		victim->pcdata->condition[COND_THIRST] =
		    race_table[victim->race].thirst_mod * 10;
	    }
	    update_pos( victim );
	    if( mesg )
	    {
		sprintf( buf, "&g%s has restored you.&n\n\r", argument );
		send_to_char( buf, victim );
	    }
	    else
		act( "&g$n has restored you.&n", ch, NULL, victim, TO_VICT );
	}
	send_to_char( "&bAww...how sweet &Y:)&b . . . Done.&n\n\r", ch );
    }
    else
    {
	int i;
	if( !( victim = get_char_world( ch, arg ) ) )
	{
	    send_to_char( "They aren't here.\n\r", ch );
	    return;
	}

	victim->hit = victim->max_hit;
	for( i = 0; i < MAGIC_MAX; ++i )
	    victim->mana[i] = victim->max_mana[i];
	victim->move = victim->max_move;
	xREMOVE_BIT( victim->affected_by, AFF_BLEEDING );
	if( parts )
	    victim->body_parts = race_table[victim->race].body_parts;
	if( !IS_NPC( victim ) )
	{
	    victim->pcdata->condition[COND_FULL] =
		race_table[victim->race].hunger_mod * 10;
	    victim->pcdata->condition[COND_THIRST] =
		race_table[victim->race].thirst_mod * 10;
	}
	update_pos( victim );
	if( mesg )
	{
	    sprintf( buf, "&g%s has restored you.&n\n\r", argument );
	    send_to_char( buf, victim );
	}
	else
	    act( "&g$n has restored you.", ch, NULL, victim, TO_VICT );
	send_to_char( "Ok.\n\r", ch );
    }

    return;
}


void do_toad( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg[MAX_INPUT_LENGTH];
    MOB_INDEX_DATA *pMobIndex;
    CHAR_DATA *pMob;

    rch = get_char( ch );

    if( !authorized( rch, "toad" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Usage: TOAD <char> <mob-vnum>\n\r", ch );
	return;
    }

    argument = one_argument( argument, arg );
    if( !( victim = get_char_world( ch, arg ) ) || !victim->in_room )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) || !victim->desc )
    {
	send_to_char( "Not on NPC's or those without descriptors.\n\r", ch );
	return;
    }

    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "You failed.\n\r", ch );
	return;
    }

    if( !( pMobIndex = get_mob_index( atoi( argument ) ) ) )
    {
	send_to_char( "You can't find that mob.\n\r", ch );
	return;
    }

    pMob = create_mobile( pMobIndex );
    pMob->gold = 0;

    victim->pcdata->switched = TRUE;
    victim->desc->character = pMob;
    victim->desc->original = victim;
    pMob->desc = victim->desc;
    victim->desc = NULL;

    char_to_room( pMob, victim->in_room );
    char_from_room( victim );
    char_to_room( victim, get_room_index( ROOM_VNUM_TEMPLE ) );

    charprintf( pMob, "&r%s has turned you into %s!\n\r",
		ch->name, pMob->short_descr );
    charprintf( ch, "&gYou have turned %s into %s!\n\r",
		victim->name, pMob->short_descr );
    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s has turned %s into %s.",
	     rch->name, victim->name, pMob->short_descr );
    return;
}


void do_freeze( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;

    rch = get_char( ch );

    if( !authorized( rch, "freeze" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Freeze whom?\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "You failed.\n\r", ch );
	return;
    }

    if( xIS_SET( victim->act, PLR_FREEZE ) )
    {
	xREMOVE_BIT( victim->act, PLR_FREEZE );
	send_to_char( "&CFREEZE&g removed.&n\n\r", ch );
	send_to_char( "&gYou can play again.&n\n\r", victim );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has thawed %s.", rch->name, victim->name );
    }
    else
    {
	xSET_BIT( victim->act, PLR_FREEZE );
	send_to_char( "&CFREEZE&r set.&n\n\r", ch );
	send_to_char( "&rYou can't do &RANYthing!&n\n\r", victim );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has frozen %s.", rch->name, victim->name );
    }

    save_char_obj( victim );

    return;
}


void do_log( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;

    rch = get_char( ch );

    if( !authorized( rch, "log" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Log whom?\n\r", ch );
	return;
    }

    if( !str_cmp( argument, "all" ) )
    {
	TOGGLE_BIT( SysInfo->flags, SYSINFO_LOGALL );
	if( IS_SET( SysInfo->flags, SYSINFO_LOGALL ) )
	{
	    send_to_char( "Log ALL on.\n\r", ch );
	    wiznetf( ch, WIZ_MISC, get_trust( ch ),
		     "%s has set log for the entire MUD.", rch->name );
	}
	else
	{
	    send_to_char( "Log ALL off.\n\r", ch );
	    wiznetf( ch, WIZ_MISC, get_trust( ch ),
		     "%s has removed log for the entire MUD.", rch->name );
	}
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    /*
     * No level check, gods can log anyone.
     */
    if( xIS_SET( victim->act, PLR_LOG ) )
    {
	xREMOVE_BIT( victim->act, PLR_LOG );
	send_to_char( "LOG removed.\n\r", ch );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has removed log for %s.", rch->name, victim->name );
    }
    else
    {
	xSET_BIT( victim->act, PLR_LOG );
	send_to_char( "LOG set.\n\r", ch );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has set log for %s.", rch->name, victim->name );
    }

    return;
}


void do_noemote( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;

    rch = get_char( ch );

    if( !authorized( rch, "noemote" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Noemote whom?\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "You failed.\n\r", ch );
	return;
    }

    if( xIS_SET( victim->act, PLR_NO_EMOTE ) )
    {
	xREMOVE_BIT( victim->act, PLR_NO_EMOTE );
	send_to_char( "NO_EMOTE removed.\n\r", ch );
	send_to_char( "You can emote again.\n\r", victim );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has removed noemote for %s.", rch->name, victim->name );
    }
    else
    {
	xSET_BIT( victim->act, PLR_NO_EMOTE );
	send_to_char( "You can't emote!\n\r", victim );
	send_to_char( "NO_EMOTE set.\n\r", ch );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has set noemote for %s.", rch->name, victim->name );
    }

    return;
}


void do_notell( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;

    rch = get_char( ch );

    if( !authorized( rch, "notell" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Notell whom?", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "You failed.\n\r", ch );
	return;
    }

    if( xIS_SET( victim->act, PLR_NO_TELL ) )
    {
	xREMOVE_BIT( victim->act, PLR_NO_TELL );
	send_to_char( "NO_TELL removed.\n\r", ch );
	send_to_char( "You can tell again.\n\r", victim );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has removed notell for %s.", rch->name, victim->name );
    }
    else
    {
	xSET_BIT( victim->act, PLR_NO_TELL );
	send_to_char( "NO_TELL set.\n\r", ch );
	send_to_char( "You can't tell!\n\r", victim );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has set notell for %s.", rch->name, victim->name );
    }

    return;
}


void do_silence( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;

    rch = get_char( ch );

    if( !authorized( rch, "silence" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Silence whom?\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "You failed.\n\r", ch );
	return;
    }

    if( xIS_SET( victim->act, PLR_SILENCE ) )
    {
	xREMOVE_BIT( victim->act, PLR_SILENCE );
	send_to_char( "You can use channels again.\n\r", victim );
	send_to_char( "SILENCE removed.\n\r", ch );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has unsilenced %s.", rch->name, victim->name );
    }
    else
    {
	xSET_BIT( victim->act, PLR_SILENCE );
	send_to_char( "You can't use channels!\n\r", victim );
	send_to_char( "SILENCE set.\n\r", ch );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has silenced %s.", rch->name, victim->name );
    }

    return;
}


void do_peace( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "peace" ) )
	return;

    /*
     * Yes, we are reusing rch.	 -Kahn
     * --
     * Removal of aggressive flag from ROM
     */
    for( rch = ch->in_room->people; rch; rch = rch->next_in_room )
    {
	if( rch->fighting )
	    stop_fighting( rch, TRUE );
	if( IS_NPC( rch ) && xIS_SET( rch->act, ACT_AGGRESSIVE ) )
	    xREMOVE_BIT( rch->act, ACT_AGGRESSIVE );
    }

    send_to_char( "Ok.\n\r", ch );
    return;
}


void do_badname( CHAR_DATA *ch, const char *argument )
{
    BAN_DATA *pbad;
    CHAR_DATA *rch;
    char buf[MAX_STRING_LENGTH];
    char arg[MAX_INPUT_LENGTH];
    int col = 0;

    if( IS_NPC( ch ) )
	return;

    rch = get_char( ch );

    if( !authorized( rch, "badname" ) )
	return;

    argument = one_argument( argument, arg );

    if( arg[0] == '\0' )
    {
	strcpy( buf, "Banned character names:\n\r" );
	for( pbad = badname_list; pbad; pbad = pbad->next )
	{
	    sprintf( buf + strlen( buf ), "%-15s", pbad->name );
	    if( ++col % 5 == 0 )
		strcat( buf, "\n\r" );
	    else
		strcat( buf, " " );
	}
	if( col % 5 != 0 )
	    strcat( buf, "\n\r" );
	send_to_char( buf, ch );
	return;
    }

    if( !str_cmp( arg, "remove" ) )
    {
	BAN_DATA *prev, *curr;
	char arg2[MAX_INPUT_LENGTH];

	one_argument( argument, arg2 );
	prev = NULL;
	for( curr = badname_list; curr; prev = curr, curr = curr->next )
	{
	    if( !str_cmp( arg2, curr->name ) )
	    {
		if( !prev )
		    badname_list = badname_list->next;
		else
		    prev->next = curr->next;

		free_string( curr->name );
		curr->next = ban_free;
		ban_free = curr;
		charprintf( ch, "Unbanned the name %s.\n\r", arg2 );
		wiznetf( ch, WIZ_MISC, get_trust( ch ),
			 "%s removing the ban on the name %s.",
			 ch->name, arg2 );
		return;
	    }
	}
	charprintf( ch, "The name %s isn't banned.\n\r", arg2 );
	return;
    }
    for( pbad = badname_list; pbad; pbad = pbad->next )
    {
	if( !str_cmp( arg, pbad->name ) )
	{
	    send_to_char( "That name is already banned!\n\r", ch );
	    return;
	}
    }

    if( !ban_free )
    {
	pbad = alloc_perm( sizeof( *pbad ) );
    }
    else
    {
	pbad = ban_free;
	ban_free = ban_free->next;
    }

    pbad->name = str_dup( arg );
    pbad->next = badname_list;
    badname_list = pbad;

    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s banning the name %s",
	     ch->name, arg );
    charprintf( ch, "Banned the name %s.\n\r", arg );
    return;
}


void do_ban( CHAR_DATA *ch, const char *argument )
{
    BAN_DATA *pban;
    CHAR_DATA *rch;
    char buf[MAX_STRING_LENGTH];
    char arg[MAX_INPUT_LENGTH];

    if( IS_NPC( ch ) )
	return;

    rch = get_char( ch );

    if( !authorized( rch, "ban" ) )
	return;

    one_argument( argument, arg );

    if( arg[0] == '\0' )
    {
	strcpy( buf, "Banned sites:\n\r" );
	for( pban = ban_list; pban; pban = pban->next )
	{
	    strcat( buf, pban->name );
	    strcat( buf, "\n\r" );
	}
	send_to_char( buf, ch );
	return;
    }

    for( pban = ban_list; pban; pban = pban->next )
    {
	if( !str_cmp( arg, pban->name ) )
	{
	    send_to_char( "That site is already banned!\n\r", ch );
	    return;
	}
    }

    if( !ban_free )
    {
	pban = alloc_perm( sizeof( *pban ) );
    }
    else
    {
	pban = ban_free;
	ban_free = ban_free->next;
    }

    pban->name = str_dup( arg );
    pban->next = ban_list;
    ban_list = pban;
    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s setting siteban on %s",
	    ch->name, arg );
    send_to_char( "Ok.\n\r", ch );
    ban_update( );
    return;
}


void do_allow( CHAR_DATA *ch, const char *argument )
{
    BAN_DATA *prev;
    BAN_DATA *curr;
    CHAR_DATA *rch;
    char arg[MAX_INPUT_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "allow" ) )
	return;

    one_argument( argument, arg );

    if( arg[0] == '\0' )
    {
	send_to_char( "Remove which site from the ban list?\n\r", ch );
	return;
    }

    prev = NULL;
    for( curr = ban_list; curr; prev = curr, curr = curr->next )
    {
	if( !str_cmp( arg, curr->name ) )
	{
	    if( !prev )
		ban_list = ban_list->next;
	    else
		prev->next = curr->next;

	    free_string( curr->name );
	    curr->next = ban_free;
	    ban_free = curr;
	    send_to_char( "Ok.\n\r", ch );
	    ban_update( );
	    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s allowing site %s.",
		     ch->name, arg );
	    return;
	}
    }

    send_to_char( "Site is not banned.\n\r", ch );
    return;
}


void do_wizlock( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "wizlock" ) )
	return;

    TOGGLE_BIT( SysInfo->flags, SYSINFO_WIZLOCK );

    if( IS_SET( SysInfo->flags, SYSINFO_WIZLOCK ) )
	send_to_char( "Game wizlocked.\n\r", ch );
    else
	send_to_char( "Game un-wizlocked.\n\r", ch );

    return;
}


void do_slookup( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    BUFFER *buf;
    int sn, i, k, j;
    const char *ptr;

    rch = get_char( ch );

    if( !authorized( rch, "slookup" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Slookup what?\n\r", ch );
	return;
    }

    if( !str_cmp( argument, "all" ) )
    {
	buf = buffer_new( MAX_STRING_LENGTH );
	for( sn = 0; sn < MAX_SKILL; sn++ )
	{
	    if( !skill_table[sn].name )
		break;
	    bprintf( buf, "Sn: %4d Skill/spell: '%s'\n\r",
		     sn, skill_table[sn].name );
	}
    }
    else
    {
	if( is_number( argument ) )
	{
	    sn = atoi( argument );
	    if( sn < 0 || sn >= MAX_SKILL || !skill_table[sn].name )
	    {
		send_to_char( "I can't find that skill.\n\r", ch );
		return;
	    }
	}
	else if( ( sn = skill_lookup( argument ) ) < 0 )
	{
	    send_to_char( "No such skill or spell.\n\r", ch );
	    return;
	}

	buf = buffer_new( MAX_STRING_LENGTH );

	bprintf( buf, "&gSn: &b[&r%5d&b] &gSkill/spell: &c'%s'&n\n\r",
		 sn, skill_table[sn].name );

	switch( skill_table[sn].target )
	{
	case TAR_CHAR_DEFENSIVE:
	    ptr = "defensive";		break;
	case TAR_CHAR_SELF:
	    ptr = "self only";		break;
	case TAR_CHAR_OFFENSIVE:
	    ptr = "offensive";		break;
	case TAR_OBJ_INV:
	    ptr = "object";		break;
	default:
	case TAR_IGNORE:
	    ptr = "generic";		break;
	}
	bprintf( buf, "&gTarget type:  &b[&c%-10s&b]  ", ptr );
	i = skill_table[sn].minimum_position;
	bprintf( buf, "&gPosition: &b[&c%s&b]&n\n\r",
		 flag_string( position_flags, &i ) );
	bprintf( buf, "&gSpell Func.:  &b[&c%-3s&b]         ",
		 ( skill_table[sn].spell_fun
		   && skill_table[sn].spell_fun != spell_null )
		 ? "yes" : "no" );
	bprintf( buf, "&gGSN:      &b[&c%-3s&b]&n\n\r",
		 skill_table[sn].pgsn ? "yes" : "no" );
	bprintf( buf, "&gDelay:        &b[&c%5ds&b]      ",
		 (int)( skill_table[sn].beats / PULSE_PER_SECOND ) );
	buffer_strcat( buf, "&gMana:     " );
	for( i = 0; i < MAGIC_MAX; ++i )
	    bprintf( buf, "%s%d&g/", magic_colour[i],
		     skill_table[sn].min_mana[i] );
	bprintf( buf, "%d&n\n\r", skill_table[sn].min_mana[MAGIC_MAX] );
	i = skill_table[sn].skill_type;
	bprintf( buf, "&gType:         &b[&c%s&b]&n\n\r",
		 flag_string( skill_type_flags, &i ) );
	if( skill_table[sn].noun_damage && skill_table[sn].noun_damage[0] )
	    bprintf( buf, "&gDamage Verb:  &w%s&n\n\r",
		     skill_table[sn].noun_damage );
	if( skill_table[sn].msg_off && skill_table[sn].msg_off[0] )
	    bprintf( buf, "&gWear Off Msg: &w%s&n\n\r",
		     skill_table[sn].msg_off );

	/* Format the level information like in const.c */
	k = 0;
	for( i = 0; i < MAX_CLASS; )
	{
	    if( k >= AVAIL_CLASS )
		k = MAX_CLASS - i - 1;
	    for( j = 0; j < k; ++j )
		bprintf( buf, "          " );

	    for( ; j < AVAIL_CLASS; ++j )
	    {
		bprintf( buf, "&g%s: &c%3d&r%c ",
			 class_table[i].who_name,
			 skill_table[sn].skill_level[i],
			 (skill_table[sn].skill_level[i] > LEVEL_HERO) ? ' ' : '*' );
		++i;
	    }
	    buffer_strcat( buf, "&n\n\r" );
	    if( i > AVAIL_CLASS )
		k++;
	}
    }
    send_to_char( buf->data, ch );
    buffer_free( buf );

    return;
}


void do_sset( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    char arg3[MAX_INPUT_LENGTH];
    int value;
    int sn;
    bool fAll;

    rch = get_char( ch );

    if( !authorized( rch, "sset" ) )
	return;

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );
    one_argument( argument, arg3 );

    if( arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' )
    {
	send_to_char( "Syntax: sset <victim> <skill> <value>\n\r", ch );
	send_to_char( "or:     sset <victim> all     <value>\n\r", ch );
	send_to_char( "Skill being any skill or spell.\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, arg1 ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( ch->level <= victim->level && ch != victim )
    {
	send_to_char( "You may not sset your peer nor your superior.\n\r",
		     ch );
	return;
    }

    fAll = !str_cmp( arg2, "all" );
    sn = 0;
    if( !fAll && ( sn = skill_lookup( arg2 ) ) < 0 )
    {
	send_to_char( "No such skill or spell.\n\r", ch );
	return;
    }

    /*
     * Snarf the value.
     */
    if( !is_number( arg3 ) )
    {
	send_to_char( "Value must be numeric.\n\r", ch );
	return;
    }

    value = atoi( arg3 );
    if( value < 0 || value > ( get_trust( ch ) - 750 ) )
    {
	send_to_char( "Value range is 0 to 100.\n\r", ch );
	return;
    }

    if( fAll )
    {
	if( get_trust( ch ) < L_MAS )
	{
	    send_to_char( "Only Masters may sset all.\n\r", ch );
	    return;
	}
	for( sn = 0; sn < MAX_SKILL; sn++ )
	{
	    if( skill_table[sn].name )
	    {
		if( can_prac( victim, sn ) )
		    victim->pcdata->learned[sn] = value;
		else
		    victim->pcdata->learned[sn] = 1;
	    }
	}
    }
    else
    {
	victim->pcdata->learned[sn] = value;
    }

    return;
}


void do_mset( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    char arg3[MAX_INPUT_LENGTH];
    int value;
    int max;

    rch = get_char( ch );

    if( !authorized( rch, "mset" ) )
	return;

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );
    strcpy( arg3, argument );

    if( arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' )
    {
	send_to_char( "Syntax: mset <victim> <field>  <value>\n\r"
		      "or:     mset <victim> <string> <value>\n\r\n\r"
		      "Field being one of:\n\r"
		      "   str int wis dex con class sex race gold hp\n\r"
		      "   move practice align thirst drunk full\n\r"
		      "   level sublevel security qscore qtime multi\n\r"
		      "   religion clan clanrank\n\r"
		      "   magic<sphere> mana<sphere>\n\r"
		      "String being one of:\n\r"
		      "   name short long title spec\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, arg1 ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    /*
     * Snarf the value (which need not be numeric).
     */
    value = atoi_functions( arg3 );

    /*
     * Set something.
     */
    if( !str_cmp( arg2, "class" ) )
    {
	if( value < 0 || value >= MAX_CLASS )
	{
	    for( value = 0; value < MAX_CLASS; value++ )
	    {
		if( !str_cmp( arg3, class_table[value].who_name )
		    || !str_cmp( arg3, class_table[value].name ) )
		    break;
	    }

	    if( value >= MAX_CLASS )
	    {
		send_to_char( "That isn't a class.\n\r", ch );
		return;
	    }
	    victim->class = value;
	    return;
	}
	if( value == -1 && !IS_NPC( ch ) )
	{
	    send_to_char( "-1 only on mobiles.\n\r", ch );
	    return;
	}
	victim->class = value;
	return;
    }

    if( !str_cmp( arg2, "sex" ) )
    {
	if( IS_AFFECTED( victim, AFF_POLYMORPH ) )
	{
	    send_to_char( "This person is affect by polymorph.n\r", ch );
	    send_to_char( "Try again later.\n\r", ch );
	    return;
	}

	if( value < 0 || value > 2 )
	{
	    if( !str_cmp( arg3, "male" ) )
		victim->sex = SEX_MALE;
	    else if( !str_cmp( arg3, "female" ) )
		victim->sex = SEX_FEMALE;
	    else if( !str_cmp( arg3, "neuter" ) )
		victim->sex = SEX_NEUTRAL;
	    else
		send_to_char( "Sex range is 0 to 2.\n\r", ch );
	    return;
	}

	victim->sex = value;

	return;
    }

    if( !str_cmp( arg2, "race" ) )
    {
	OBJ_DATA *wield;
	OBJ_DATA *wield2;
	int race;

	if( IS_AFFECTED( victim, AFF_POLYMORPH ) )
	{
	    send_to_char( "This person is affected by polymorph other.\n\r",
			  ch );
	    send_to_char( "Try again later.\n\r", ch );
	    return;
	}

	race = race_lookup( arg3 );

	if( race < 0 )
	{
	    send_to_char( "Invalid race.\n\r", ch );
	    return;
	}

	if( IS_SET( race_table[race].race_abilities, RACE_NPC_ONLY )
	    && get_trust( ch ) < L_OVL )
	{
	    send_to_char( "You may not set a race not available to PC's.\n\r",
			  ch );
	    return;
	}

	victim->race = race;

	if( ( wield = get_eq_char( victim, WEAR_WIELD_R ) )
	    && IS_SET( race_table[victim->race].race_abilities,
		       RACE_NO_WEAPON_WIELD ) )
	{
	    act( "You drop $p.", victim, wield, NULL, TO_CHAR );
	    act( "$n drops $p.", victim, wield, NULL, TO_ROOM );
	    obj_from_char( wield );
	    obj_to_room( wield, victim->in_room );
	}

	if( ( wield2 = get_eq_char( victim, WEAR_WIELD_L ) )
	    && IS_SET( race_table[victim->race].race_abilities,
		       RACE_NO_WEAPON_WIELD ) )
	{
	    act( "You drop $p.", victim, wield2, NULL, TO_CHAR );
	    act( "$n drops $p.", victim, wield2, NULL, TO_ROOM );
	    obj_from_char( wield2 );
	    obj_to_room( wield2, victim->in_room );
	}

	return;
    }

    if( !str_cmp( arg2, "sublevel" ) )
    {
	if( value < 0 || value > victim->level )
	{
	    send_to_char( "Sublevel range is 0 to victim's level.\n\r", ch );
	    return;
	}
	victim->sublevel = value;
	return;
    }

    if( !str_cmp( arg2, "gold" ) )
    {
	victim->gold = value;
	return;
    }

    if( !str_cmp( arg2, "hp" ) )
    {
	if( value < -10 || value > 1000000 )
	{
	    send_to_char( "Hp range is -10 to 1 million hit points.\n\r", ch );
	    return;
	}
	if( victim->fighting && value < 0 )
	{
	    send_to_char( "You cannot set a fighting person's hp below 0.\n\r",
			  ch );
	    return;
	}
	victim->max_hit = value;
	return;
    }

    if( !str_prefix( "mana", arg2 ) )
    {
	int which;
	if( value < 0 || value > 1000000 )
	{
	    send_to_char( "Mana range is 0 to 1 million mana points.\n\r", ch );
	    return;
	}
	argument = &arg2[4];
	while( isspace( *argument ) )
	    argument++;
	if( !str_cmp( argument, "air" ) )
	    which = MAGIC_AIR;
	else if( !str_cmp( argument, "earth" ) )
	    which = MAGIC_EARTH;
	else if( !str_cmp( argument, "fire" ) )
	    which = MAGIC_FIRE;
	else if( !str_cmp( argument, "spirit" ) )
	    which = MAGIC_SPIRIT;
	else if( !str_cmp( argument, "water" ) )
	    which = MAGIC_WATER;
	else
	{
	    send_to_char( "Please specify which sphere, ie 'mana air'.\n\r", ch );
	    return;
	}
	victim->max_mana[which] = value;
	return;
    }

    if( !str_cmp( arg2, "move" ) )
    {
	if( value < 0 || value > 1000000 )
	{
	    send_to_char( "Move range is 0 to 1 million move points.\n\r", ch );
	    return;
	}
	victim->max_move = value;
	return;
    }

    if( !str_cmp( arg2, "practice" ) )
    {
	if( value < 0 || value > 10000 )
	{
	    send_to_char( "Practice range is 0 to 10,000 sessions.\n\r", ch );
	    return;
	}
	victim->practice = value;
	return;
    }

    if( !str_cmp( arg2, "align" ) )
    {
	if( value < -1000 || value > 1000 )
	{
	    send_to_char( "Alignment range is -1000 to 1000.\n\r", ch );
	    return;
	}
	victim->alignment = value;
	return;
    }

    if( !IS_NPC( victim ) )
    {
	if( !str_cmp( arg2, "str" ) )
	{
	    if( class_table[victim->class].attr_prime == APPLY_STR )
		max = 50;
	    else
		max = 40;

	    if( value < 3 || value > max )
	    {
		charprintf( ch, "Strength range is 3 to %d.\n\r", max );
		return;
	    }

	    victim->pcdata->perm_str = value;
	    return;
	}

	if( !str_cmp( arg2, "int" ) )
	{
	    if( class_table[victim->class].attr_prime == APPLY_INT )
		max = 50;
	    else
		max = 40;

	    if( value < 3 || value > max )
	    {
		charprintf( ch, "Intelligence range is 3 to %d.\n\r", max );
		return;
	    }

	    victim->pcdata->perm_int = value;
	    return;
	}

	if( !str_cmp( arg2, "wis" ) )
	{
	    if( class_table[victim->class].attr_prime == APPLY_WIS )
		max = 50;
	    else
		max = 40;

	    if( value < 3 || value > max )
	    {
		charprintf( ch, "Wisdom range is 3 to %d.\n\r", max );
		return;
	    }

	    victim->pcdata->perm_wis = value;
	    return;
	}

	if( !str_cmp( arg2, "dex" ) )
	{
	    if( class_table[victim->class].attr_prime == APPLY_DEX )
		max = 50;
	    else
		max = 40;

	    if( value < 3 || value > max )
	    {
		charprintf( ch, "Dexterity range is 3 to %d.\n\r", max );
		return;
	    }

	    victim->pcdata->perm_dex = value;
	    return;
	}

	if( !str_cmp( arg2, "con" ) )
	{
	    if( class_table[victim->class].attr_prime == APPLY_CON )
		max = 50;
	    else
		max = 40;

	    if( value < 3 || value > max )
	    {
		charprintf( ch, "Constitution range is 3 to %d.\n\r", max );
		return;
	    }

	    victim->pcdata->perm_con = value;
	    return;
	}

	if( !str_cmp( arg2, "multi" ) )
	{
	    char classbuf[ MAX_INPUT_LENGTH ];

	    if( !str_cmp( argument, "all clear" ) )
	    {
		victim->class = get_first_class( victim );
		for( value = 0; value < AVAIL_CLASS; value++ )
		    victim->pcdata->multi_class[value] = CLASS_UNKNOWN;
		send_to_char( "All multiclassing cleared.\n\r", ch );
		return;
	    }

	    argument = one_argument( argument, classbuf );
	    for( value = 0; value < AVAIL_CLASS; value++ )
		if( !str_cmp( classbuf, class_table[value].who_name )
		    || !str_cmp( classbuf, class_table[value].name ) )
		    break;
	    if( value >= AVAIL_CLASS )
	    {
		send_to_char( "You can't set multiclass for that class.\n\r", ch );
		send_to_char( "mset multi all clear - clear all multiclassing.\n\r"
			      "mset multi [class] [level] - set class multiclass level.\n\r"
			      "[level] can be 'clear', 'aspire' or 'adept'.\n\r",
			      ch );
		return;

	    }

	    if( !str_cmp( argument, "clear" ) )
	    {
		if( victim->pcdata->multi_class[value] > CLASS_ADEPT )
		{
		    send_to_char( "You can't clear first or second classes\n\r"
				  " use 'all clear' instead.\n\r", ch );
		    return;
		}
		victim->pcdata->multi_class[value] = CLASS_UNKNOWN;
		if( victim->sublevel )
		    victim->sublevel = 0;
		send_to_char( "Multi-class cleared.\n\r", ch );
		return;
	    }
	    if( !str_cmp( argument, "aspire" ) )
	    {
		if( get_aspire_class( victim ) >= 0 )
		{
		    send_to_char( "You can't set that now.\n\r", ch );
		    return;
		}
		victim->pcdata->multi_class[value] = CLASS_ASPIRING;
		send_to_char( "Aspiring set.\n\r", ch );
		return;
	    }
	    if( !str_cmp( argument, "adept" ) )
	    {
		if( victim->pcdata->multi_class[value] > CLASS_ADEPT )
		{
		    send_to_char( "They are more than adept at that now.\n\r", ch );
		    return;
		}
		victim->pcdata->multi_class[value] = CLASS_ADEPT;
		send_to_char( "Adept set.\n\r", ch );
		return;
	    }

	    send_to_char( "You can only set clear, aspire or adept.\n\r", ch );
	    send_to_char( "'all clear' clears all classes.\n\r", ch );
	    return;
	}

	if( !str_cmp( arg2, "security" ) )
	{
	    if( value < 0 || value > get_trust( ch ) / 20 - 40 )
	    {
		send_to_char( "That is too high a trust for you to set.\n\r", ch );
		return;
	    }
	    victim->pcdata->security = value;
	    return;
	}

	if( !str_cmp( arg2, "qscore" ) )
	{
	    if( value < 0 || value > 10000 )
	    {
		send_to_char( "Quest points between 0 and 10000 only.\n\r", ch );
		return;
	    }
	    victim->pcdata->quest->score = value;
	    return;
	}

	if( !str_cmp( arg2, "qtime" ) )
	{
	    if( value < 0 || value > 60 )
	    {
		send_to_char( "Time only from 0 to 60 minutes.\n\r", ch );
		return;
	    }
	    victim->pcdata->quest->time = value;
	    return;
	}
	if( !str_prefix( "magic", arg2 ) )
	{
	    int which;

	    if( value < 0 || value > 100 )
	    {
		send_to_char( "Magic range is 0 to 100 points.\n\r", ch );
		return;
	    }
	    argument = &arg2[5];
	    while( isspace( *argument ) )
		argument++;
	    if( !str_cmp( argument, "air" ) )
		which = MAGIC_AIR;
	    else if( !str_cmp( argument, "earth" ) )
		which = MAGIC_EARTH;
	    else if( !str_cmp( argument, "fire" ) )
		which = MAGIC_FIRE;
	    else if( !str_cmp( argument, "spirit" ) )
		which = MAGIC_SPIRIT;
	    else if( !str_cmp( argument, "water" ) )
		which = MAGIC_WATER;
	    else
	    {
		send_to_char( "Please specify which sphere, ie 'mana air'.\n\r", ch );
		return;
	    }
	    victim->pcdata->perm_magic[which] = value;
	    return;
	}

	if( !str_cmp( arg2, "thirst" ) )
	{
	    if( ( value < 0 || value > 250 )
		&& get_trust( victim ) < LEVEL_IMMORTAL )
	    {
		send_to_char( "Thirst range is 0 to 250.\n\r", ch );
		return;
	    }
	    else if( value < -1 || value > 250 )
	    {
		send_to_char( "Thirst range is -1 to 250.\n\r", ch );
		return;
	    }

	    victim->pcdata->condition[COND_THIRST] = value * 10;
	    return;
	}

	if( !str_cmp( arg2, "drunk" ) )
	{
	    if( value < 0 || value > 100 )
	    {
		send_to_char( "Drunk range is 0 to 100.\n\r", ch );
		return;
	    }

	    victim->pcdata->condition[COND_DRUNK] = value * 10;
	    return;
	}

	if( !str_cmp( arg2, "full" ) )
	{
	    if( ( value < 0 || value > 250 )
		&& get_trust( victim ) < LEVEL_IMMORTAL )
	    {
		send_to_char( "Full range is 0 to 250.\n\r", ch );
		return;
	    }
	    else if( value < -1 || value > 250 )
	    {
		send_to_char( "Full range is -1 to 250.\n\r", ch );
		return;
	    }

	    victim->pcdata->condition[COND_FULL] = value * 10;
	    return;
	}
	if( !str_cmp( arg2, "clan" ) )
	{
	    CLAN_DATA *clan;

	    if( !str_cmp( arg3, "none" ) )
	    {
		if( is_clan( victim ) )
		    remove_from_clan( victim );
		send_to_char( "Victim removed from clan, Ok.\n\r", ch );
		return;
	    }
	    if( !( clan = clan_lookup( arg3 ) ) )
	    {
		send_to_char( "That clan doesn't exist.\n\r", ch );
		return;
	    }

	    if( victim->pcdata->clan == clan )
		return;
	    if( is_clan( victim ) )
		remove_from_clan( victim );
	    add_to_clan( victim, clan, RANK_CLANSMAN );
	    send_to_char( "Clan set.\n\r", ch );
	    return;
	}

	if( !str_cmp( arg2, "religion" ) )
	{
	    RELIGION_DATA *religion;

	    if ( !( religion = religion_lookup( arg3 ) ) )
	    {
		send_to_char( "That religion doesn't exist.\n\r", ch );
		return;
	    }

	    victim->pcdata->religion = religion;
	    send_to_char( "Religion set.\n\r", ch );
	    return;
	}

	if( !str_cmp( arg2, "clanrank" ) )
	{
	    CLAN_DATA *clan;

	    if( !( clan = victim->pcdata->clan ) )
	    {
		send_to_char( "They don't belong to a clan.\n\r", ch );
		return;
	    }

	    if( value < RANK_EXILED )
	    {
		remove_from_clan( victim );
		send_to_char( "Ok.\n\r", ch );
		return;
	    }
	    if( value > RANK_OVERLORD )
	    {
		charprintf( ch, "Range is from %d to %d.\n\r",
			    RANK_NONE, RANK_OVERLORD );
		return;
	    }
	    if( victim->pcdata->clan_rank == value )
	    {
		send_to_char( "You can't change that person's rank.\n\r", ch );
		return;
	    }

	    switch( value )
	    {
	    default:
		break;
	    case RANK_CLANHERO:
		if( clan->clanheros >= clan->members / 3 )
		{
		    charprintf(
			ch, "You may have only 1 %s per 3 %s.\n\r",
			rank_name( RANK_CLANHERO, clan->clan_type ),
			rank_name( RANK_CLANSMAN, clan->clan_type ) );
		    return;
		}
		break;
	    case RANK_CHIEFTAIN:
		if( clan->members < 10 )
		{
		    charprintf(
			ch, "You need to have 9 %ss before you can have a %s.\n\r",
			rank_name( RANK_CLANHERO, clan->clan_type ),
			rank_name( RANK_CHIEFTAIN, clan->clan_type ) );
		    return;
		}
		break;
	    case RANK_OVERLORD:
		if( clan->overlord != NULL && clan->overlord[0] != '\0' )
		{
		    send_to_char( "The clan already has a leader.\n\r", ch );
		    return;
		}
		break;
	    }
	    remove_from_clan( victim );
	    add_to_clan( victim, clan, value );
	    send_to_char( "Clan rank set.\n\r", ch );
	    return;
	}

	if( !str_cmp( arg2, "title" ) )
	{
	    set_title( victim, arg3 );
	    return;
	}

    }
    else	/* Mobiles only */
    {
	if( !str_cmp( arg2, "level" ) )
	{
	    if( value < 0 || value > MAX_LEVEL )
	    {
		send_to_char( "Level range is 0 to hero.\n\r", ch );
		return;
	    }
	    victim->level = value;
	    return;
	}

	if( !str_cmp( arg2, "name" ) )
	{
	    if( longstring( ch, arg3 ) )
		return;

	    free_string( victim->name );
	    victim->name = str_dup( arg3 );
	    return;
	}

	if( !str_cmp( arg2, "spec" ) )
	{
	    if( ( victim->spec_fun = spec_lookup( arg3 ) ) == 0 )
	    {
		send_to_char( "No such spec fun.\n\r", ch );
		return;
	    }

	    return;
	}
    }

    if( !str_cmp( arg2, "short" ) )
    {
	if( longstring( ch, arg3 ) )
	    return;

	free_string( victim->short_descr );
	victim->short_descr = str_dup( arg3 );
	return;
    }

    if( !str_cmp( arg2, "long" ) )
    {
	if( longstring( ch, arg3 ) )
	    return;

	free_string( victim->long_descr );
	if( str_cmp( arg3, "clear" ) )
	{
	    strcat( arg3, "\n\r" );
	    victim->long_descr = str_dup( arg3 );
	}
	else
	    victim->long_descr = str_dup( "" );
	return;
    }

    /*
     * Generate usage message.
     */
    do_mset( ch, "" );
    return;
}


void do_oset( CHAR_DATA *ch, const char *argument )
{
    OBJ_DATA *obj;
    CHAR_DATA *rch;
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    char arg3[MAX_INPUT_LENGTH];
    int value;

    rch = get_char( ch );

    if( !authorized( rch, "oset" ) )
	return;

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );
    strcpy( arg3, argument );

    if( arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' )
    {
	send_to_char( "Syntax: oset <object> <field>  <value>\n\r", ch );
	send_to_char( "or:     oset <object> <string> <value>\n\r", ch );
	send_to_char( "\n\r", ch );
	send_to_char( "Field being one of:\n\r", ch );
	send_to_char( "   value0 value1 value2 value3 required\n\r", ch );
	send_to_char( "   extra wear level weight cost timer\n\r", ch );
	send_to_char( "   imptimer condition\n\r", ch );
	send_to_char( "\n\r", ch );
	send_to_char( "String being one of:\n\r", ch );
	send_to_char( "   name short long ed action\n\r", ch );
	return;
    }

    if( !( obj = get_obj_world( ch, arg1 ) ) )
    {
	send_to_char( "Nothing like that in hell, earth, or heaven.\n\r", ch );
	return;
    }

    /*
     * Snarf the value ( which need not be numeric ).
     */
    value = atoi_functions( arg3 );

    /*
     * Set something.
     */
    if( !str_cmp( arg2, "value0" ) || !str_cmp( arg2, "v0" ) )
    {
	obj->value[0] = value;
	return;
    }

    if( !str_cmp( arg2, "value1" ) || !str_cmp( arg2, "v1" ) )
    {
	obj->value[1] = value;
	return;
    }

    if( !str_cmp( arg2, "value2" ) || !str_cmp( arg2, "v2" ) )
    {
	obj->value[2] = value;
	return;
    }

    if( !str_cmp( arg2, "value3" ) || !str_cmp( arg2, "v3" ) )
    {
	obj->value[3] = value;
	return;
    }

    if( !str_cmp( arg2, "extra" ) )
    {
	if( !str_cmp( arg3, "clear" ) )
	{
	    obj->extra_flags = 0;
	    send_to_char( "Object extra flags cleared.\n\r", ch );
	}
	else if( flag_value( NULL, extra_flags, arg3 ) != NO_FLAG )
	{
	    TOGGLE_BIT( obj->extra_flags, flag_value( NULL, extra_flags, arg3 ) );
	    send_to_char( "Object extra flag toggled.\n\r", ch );
	}
	else
	{
	    obj->extra_flags = value;
	    send_to_char( "Object extra flags set.\n\r", ch );
	}
	return;
    }

    if( !str_cmp( arg2, "wear" ) )
    {
	if( !str_cmp( arg3, "clear" ) )
	{
	    obj->wear_flags = 0;
	    send_to_char( "Object wear flags cleared.\n\r", ch );
	}
	else if( flag_value( NULL, wear_flags, arg3 ) != NO_FLAG )
	{
	    TOGGLE_BIT( obj->wear_flags, flag_value( NULL, wear_flags, arg3 ) );
	    send_to_char( "Object wear flag toggled.\n\r", ch );
	}
	else
	{
	    obj->wear_flags = value;
	    send_to_char( "Object wear flags set.\n\r", ch );
	}
	return;
    }

    if( !str_cmp( arg2, "level" ) )
    {
	obj->level = value;
	return;
    }

    if( !str_cmp( arg2, "weight" ) )
    {
	weight_change_object( obj, obj->weight - value );
	return;
    }

    if( !str_cmp( arg2, "cost" ) )
    {
	obj->cost = value;
	send_to_char( "Cost set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "timer" ) )
    {
	if( value <= 0 )
	    strip_events( &obj->events, evn_obj_decay );
	else
	    set_timer( obj, value * PULSE_PER_SECOND );
	send_to_char( "Timer set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "imptimer" ) )
    {
	if( value <= 0 )
	    strip_events( &obj->events, evn_imp_grab );
	else
	    create_obj_event( obj, evn_imp_grab,
			      value * PULSE_PER_SECOND );

	send_to_char( "Imp timer set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "required" ) )
    {
	if( ( value <= 0 || value >= MAX_SKILL )
	    && skill_lookup( arg3 ) <= 0 )
	{
	    send_to_char( "Invalid skill no.\n\r", ch );
	    return;
	}
	obj->required_skill = ( value <= 0 || value >= MAX_SKILL )
	    ? skill_lookup( arg3 ) : value;
	send_to_char( "Required skill set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "condition" ) )
    {
	if( value <= 0 || value > 200 )
	{
	    send_to_char( "Invalid condition.\n\r", ch );
	    return;
	}
	obj->condition = value * 10;
	send_to_char( "Item condition set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "name" ) )
    {
	if( longstring( ch, arg3 ) )
	    return;

	free_string( obj->name );
	obj->name = str_dup( arg3 );
	send_to_char( "Object name set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "short" ) )
    {
	if( longstring( ch, arg3 ) )
	    return;

	free_string( obj->short_descr );
	obj->short_descr = str_dup( arg3 );
	send_to_char( "Object short set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "long" ) )
    {
	if( longstring( ch, arg3 ) )
	    return;

	strcat( arg3, "\n\r" );
	free_string( obj->description );
	obj->description = str_dup( arg3 );
	send_to_char( "Object long description set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "action" ) )
    {
	if( longstring( ch, arg3 ) )
	    return;

	strcat( arg3, "\n\r" );
	free_string( obj->action );
	obj->action = str_dup( arg3 );
	send_to_char( "Object action description set.\n\r", ch );
	return;
    }

    if( !str_cmp( arg2, "ed" ) )
    {
	EXTRA_DESCR_DATA *ed;

	for( ed = obj->extra_descr; ed; ed = ed->next )
	{
	    if( is_name( arg3, ed->keyword ) )
		break;
	}

	if( !ed )
	{
	    ed = new_extra_descr( );

	    ed->keyword = str_dup( arg3 );
	    ed->description = &str_empty[0];
	    ed->next = obj->extra_descr;
	    obj->extra_descr = ed;
	}
	string_edit( ch, &ed->description );
	return;
    }

    /*
     * Generate usage message.
     */
    do_oset( ch, "" );
    return;
}


void do_users( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    DESCRIPTOR_DATA *d;
    char buf[MAX_STRING_LENGTH * 2];
    char buf2[MAX_STRING_LENGTH];
    int count;

    rch = get_char( ch );

    if( !authorized( rch, "users" ) )
	return;

    count = 0;
    buf[0] = '\0';
    buf2[0] = '\0';
    for( d = descriptor_list; d; d = d->next )
    {
	if( d->character && can_see( ch, d->character ) )
	{
	    count++;
	    sprintf( buf + strlen( buf ), "[%3d : %-10.10s] %12s : %s\n\r",
		     d->descriptor, d->interpreter->name,
		     d->original ? d->original->name :
		     d->character ? d->character->name : "(none)",
		     d->host );
	}
	else if( !d->character )
	{
	    count++;
	    sprintf( buf + strlen( buf ),
		     "[%3d : %-10.10s] *Anonymous*  : %s\n\r",
		     d->descriptor, d->interpreter->name,
		     d->host );
	}
    }

    sprintf( buf2, "%d user%s\n\r", count, count == 1 ? "" : "s" );
    strcat( buf, buf2 );
    send_to_char( buf, ch );
    return;
}


/*
 * Thanks to Grodyn for pointing out bugs in this function.
 */
void do_force( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char arg[MAX_INPUT_LENGTH];
    int trust;
    int cmd;

    rch = get_char( ch );

    if( !authorized( rch, "force" ) )
	return;

    argument = one_argument( argument, arg );

    if( arg[0] == '\0' || argument[0] == '\0' )
    {
	send_to_char( "Force whom to do what?\n\r", ch );
	return;
    }

    /*
     * Look for command in command table.
     */
    trust = get_trust( ch );
    for( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
    {
	if( argument[0] == cmd_table[cmd].name[0]
	    && !str_prefix( argument, cmd_table[cmd].name )
	    && ( cmd_table[cmd].level > trust ) )
	{
	    send_to_char( "You can't even do that yourself!\n\r", ch );
	    return;
	}
    }

    if( !str_cmp( arg, "all" ) )
    {
	CHAR_DATA *vch;

	for( vch = char_list; vch; vch = vch->next )
	{
	    if( vch->deleted )
		continue;

	    if( !IS_NPC( vch ) && get_trust( vch ) < get_trust( ch ) )
	    {
		act( "$n forces you to '$t'.", ch, argument, vch, TO_VICT );
		interpret( vch, argument );
	    }
	}
    }
    else
    {
	CHAR_DATA *victim;

	if( !( victim = get_char_world( ch, arg ) ) )
	{
	    send_to_char( "They aren't here.\n\r", ch );
	    return;
	}

	if( victim == ch )
	{
	    send_to_char( "Feeling a little out of control?\n\r", ch );
	    return;
	}

	if( get_trust( victim ) >= get_trust( ch ) )
	{
	    send_to_char( "Maybe if you asked nicely...\n\r", ch );
	    return;
	}

	act( "$n forces you to '$t'.", ch, argument, victim, TO_VICT );
	interpret( victim, argument );
    }

    send_to_char( "Ok.\n\r", ch );
    return;
}


/*
 * Thanks to Grodyn for pointing out bugs in this function.
 */
void do_doas( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    DESCRIPTOR_DATA *orig;
    char arg[MAX_INPUT_LENGTH];
    int trust;
    int cmd;

    rch = get_char( ch );

    if( !authorized( rch, "doas" ) )
	return;

    argument = one_argument( argument, arg );

    if( arg[0] == '\0' || argument[0] == '\0' )
    {
	send_to_char( "Doas who exactly what?\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, arg ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }
    if( victim == ch )
    {
	send_to_char( "Aye aye, right away!\n\r", ch );
	return;
    }
    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "Do it yourself!\n\r", ch );
	return;
    }

    one_argument( argument, arg );

    if( !str_cmp( arg, "quit" ) )
    {
	send_to_char( "Sorry, no can do, that is _bad_.\n\r", ch );
	return;
    }
    /*
     * Look for command in command table.
     */
    trust = get_trust( ch );
    for( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
    {
	if( arg[0] == cmd_table[cmd].name[0]
	    && !str_prefix( arg, cmd_table[cmd].name )
	    && ( cmd_table[cmd].level > trust ) )
	{
	    send_to_char( "You can't even do that yourself!\n\r", ch );
	    return;
	}
    }

    act( "$n assumes control, you type '$t'.", ch, argument, victim, TO_VICT );
    orig = victim->desc;

    victim->desc = ch->desc;
    ch->desc = NULL;

    interpret( victim, argument );

    ch->desc = victim->desc;
    victim->desc = orig;
    return;
}


/*
 * New routines by Dionysos.
 *
 * Security fix (low priority) by Symposium.
 *
 * Wizinvissed immortals would show their presence by the light that they
 * leave in a room, as well as the change in the nplayer count.  This could
 * be used by some to detect them, hence wizinvis is applied while the
 * immortal is not in any room, wizinvissed immortals do not affect light.
 * Changes in char_to_room, char_from_room and do_visible.
 */
void do_invis( CHAR_DATA *ch, const char *argument )
{
    ROOM_INDEX_DATA *room = ch->in_room;

    if( IS_NPC( ch ) )
	return;

    if( !authorized( ch, "wizinvis" ) )
	return;

    if( xIS_SET( ch->act, PLR_WIZINVIS ) )
    {
	char_from_room( ch );
	xREMOVE_BIT( ch->act, PLR_WIZINVIS );
	char_to_room( ch, room );
	send_to_char( "You slowly fade back into existence.\n\r", ch );
	act( "$n slowly fades into existence.", ch, NULL, NULL, TO_ROOM );
    }
    else
    {
	char_from_room( ch );
	xSET_BIT( ch->act, PLR_WIZINVIS );
	char_to_room( ch, room );
	send_to_char( "You slowly vanish into thin air.\n\r", ch );
	act( "$n slowly fades into thin air.", ch, NULL, NULL, TO_ROOM );
    }

    return;
}


void do_holylight( CHAR_DATA *ch, const char *argument )
{
    if( IS_NPC( ch ) )
	return;

    if( !authorized( ch, "holylight" ) )
	return;

    if( xIS_SET( ch->act, PLR_HOLYLIGHT ) )
    {
	xREMOVE_BIT( ch->act, PLR_HOLYLIGHT );
	send_to_char( "Holy light mode off.\n\r", ch );
    }
    else
    {
	xSET_BIT( ch->act, PLR_HOLYLIGHT );
	send_to_char( "Holy light mode on.\n\r", ch );
    }

    return;
}


/*
 * Wizify and Wizbit sent in by M. B. King
 */
void do_wizify( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg1[MAX_INPUT_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "wizify" ) )
	return;

    one_argument( argument, arg1 );

    if( arg1[0] == '\0' )
    {
	send_to_char( "Syntax: wizify <name>\n\r", ch );
	return;
    }
    if( !( victim = get_char_world( ch, arg1 ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }
    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on mobs.\n\r", ch );
	return;
    }

    if( !xIS_SET( victim->act, PLR_WIZBIT ) )
    {
	xSET_BIT( victim->act, PLR_WIZBIT );
	act( "$N wizified.", ch, NULL, victim, TO_CHAR );
	act( "$n has wizified you!", ch, NULL, victim, TO_VICT );
	wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s has wizified %s.",
		 rch->name, victim->name );
    }
    else
    {
	xREMOVE_BIT( victim->act, PLR_WIZBIT );
	act( "$N dewizzed.", ch, NULL, victim, TO_CHAR );
	act( "$n has dewizzed you!", ch, NULL, victim, TO_VICT );
	wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s has dewizzed %s.",
		 rch->name, victim->name );
    }

    do_save( victim, "" );
    return;
}


/*
 * Idea from Talen of Vego's do_where command
 */
void do_owhere( CHAR_DATA *ch, const char *argument )
{
    OBJ_DATA *obj;
    OBJ_DATA *in_obj;
    CHAR_DATA *rch;
    char arg[MAX_INPUT_LENGTH];
    int count;
    BUFFER *buf;
    int obj_counter = 1;
    bool found = FALSE;

    rch = get_char( ch );

    if( !authorized( rch, "owhere" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:	owhere <object>.\n\r", ch );
	return;
    }
    buf = buffer_new( MAX_STRING_LENGTH );
    count = number_argument( argument, arg );
    for( obj = object_list; obj; obj = obj->next )
    {
	if( !can_see_obj( ch, obj ) || !is_obj_name( obj, arg ) )
	    continue;
	obj_counter++;
	if( --count > 0 )
	    continue;

	found = TRUE;

	for( in_obj = obj; in_obj->in_obj;
	     in_obj = in_obj->in_obj )
	    ;

	if( in_obj->carried_by )
	{
	    if( !can_see( ch, in_obj->carried_by ) )
		continue;
	    bprintf( buf, "&b[&r%2d&b] &g%s&n&w carried by "
		     "&g%s&n&w at &b[&r%4d&b]&n&w.&n\n\r",
		     obj_counter, obj->short_descr,
		     PERS( in_obj->carried_by, ch ),
		     in_obj->carried_by->in_room->vnum );
	}
	else
	{
	    bprintf( buf, "&b[&r%2d&b] &g%s&n&w in "
		     "&g%s&n&w at &b[&r%4d&b]&n&w.&n\n\r", obj_counter,
		     obj->short_descr, ( !in_obj->in_room ) ?
		     "somewhere" : in_obj->in_room->name,
		     ( !in_obj->in_room ) ?
		     0 : in_obj->in_room->vnum );
	}

	/*
	 * Only see the first 101
	 */
	if( obj_counter > 100 )
	    break;
    }

    if( !found )
	send_to_char( "Nothing like that in hell, earth, or heaven.\n\r", ch );
    else
	send_to_char( buf->data, ch );
    buffer_free( buf );
    return;
}


void do_numlock( CHAR_DATA *ch, const char *argument )	/* By Globi */
{
    CHAR_DATA *rch;
    char buf[MAX_STRING_LENGTH];
    int temp;

    rch = get_char( ch );

    if( !authorized( rch, "numlock" ) )
	return;

    temp = atoi( argument );

    if( argument[0] == '\0' )	/* Prints out the current value */
    {
	sprintf( buf, "Current numlock setting is:  %d.\n\r", SysInfo->numlock );
	send_to_char( buf, ch );
	return;
    }

    if( ( temp < 0 ) || ( temp > LEVEL_HERO ) )
    {
	sprintf( buf, "Level must be between 0 and %d.\n\r", LEVEL_HERO );
	send_to_char( buf, ch );
	return;
    }

    /* Only set SysInfo->numlock if arg supplied and within range */
    SysInfo->numlock = temp;

    if( SysInfo->numlock != 0 )
    {
	sprintf( buf, "Game numlocked to levels %d and below.\n\r", SysInfo->numlock );
	send_to_char( buf, ch );
    }
    else
	send_to_char( "Game now open to all levels.\n\r", ch );
    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s has set numlock to %d.",
	     rch->name, SysInfo->numlock );

    return;

}


void do_newlock( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char buf[MAX_STRING_LENGTH];

    rch = get_char( ch );

    if( !authorized( rch, "newlock" ) )
	return;

    if( SysInfo->numlock != 0 && get_trust( ch ) < L_SEN )
    {
	send_to_char( "You may not change the current numlock setting\n\r",
		      ch );
	sprintf( buf, "Game numlocked to levels %d and below.\n\r", SysInfo->numlock );
	send_to_char( buf, ch );
	return;
    }

    if( SysInfo->numlock != 0 )
    {
	sprintf( buf, "Game numlocked to levels %d and below.\n\r", SysInfo->numlock );
	send_to_char( buf, ch );
	send_to_char( "Changing to: ", ch );
    }

    SysInfo->numlock = 1;
    send_to_char( "Game locked to new characters.\n\r", ch );
    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s has set numlock to %d.",
	     rch->name, SysInfo->numlock );
    return;
}


void do_sstime( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    int number;

    rch = get_char( ch );

    if( !authorized( rch, "sstime" ) )
	return;

    if( !str_cmp( argument, "reboot" ) )
    {
	TOGGLE_BIT( SysInfo->flags, SYSINFO_REBOOT );
	charprintf( ch, "Reboot is %s.\n\r",
		    IS_SET( SysInfo->flags, SYSINFO_REBOOT ) ? "on" : "off" );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has just changed autoreboot settings.", rch->name );
	return;
    }

    number = atoi_special( argument );

    if( argument[0] == '\0' || number < 0 )
    {
	if( SysInfo->down_time > 0 )
	{
	    charprintf( ch, "1st warning:  %d minutes (%d seconds).\n\r",
			UMAX( ( (int)SysInfo->down_time - (int)current_time - 225 ) / 60, 0 ),
			UMAX( ( (int)SysInfo->down_time - (int)current_time - 225 ), 0 ) );
	    charprintf( ch, "2nd warning:  %d minutes (%d seconds).\n\r",
			UMAX( ( (int)SysInfo->down_time - (int)current_time - 150 ) / 60, 0 ),
			UMAX( ( (int)SysInfo->down_time - (int)current_time - 150 ), 0 ) );
	    charprintf( ch, "%s%d minutes (%d seconds).\n\r",
			IS_SET( SysInfo->flags, SYSINFO_REBOOT )
			? "Reboot:	 " : "Shutdown:	    ",
			UMAX( ( (int)SysInfo->down_time - (int)current_time ) / 60, 0 ),
			UMAX( ( (int)SysInfo->down_time - (int)current_time ), 0 ) );
	}
	else
	    send_to_char( "Automatic reboot/shutdown:  off.\n\r", ch );
	return;
    }

    /*
      Set something
      */
    if( number > 0 )
    {
	SysInfo->down_time = current_time + ( number * 60 );
	charprintf( ch, "1st warning:  %d minutes (%d seconds).\n\r",
		    UMAX( ( (int)SysInfo->down_time - (int)current_time - 225 ) / 60, 0 ),
		    UMAX( ( (int)SysInfo->down_time - (int)current_time - 225 ), 0 ) );
	charprintf( ch, "2nd warning:  %d minutes (%d seconds).\n\r",
		    UMAX( ( (int)SysInfo->down_time - (int)current_time - 150 ) / 60, 0 ),
		    UMAX( ( (int)SysInfo->down_time - (int)current_time - 150 ), 0 ) );
	charprintf( ch, "%s%d minutes (%d seconds).\n\r",
		    IS_SET( SysInfo->flags, SYSINFO_REBOOT )
		    ? "Reboot:	     " : "Shutdown:	",
		    UMAX( ( (int)SysInfo->down_time - (int)current_time ) / 60, 0 ),
		    UMAX( ( (int)SysInfo->down_time - (int)current_time ), 0 ) );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		"%s has changed reboot/shutdown time.", rch->name );
    }
    else
    {
	SysInfo->down_time = 0;
	charprintf( ch, "Auto%s is now off.\n\r",
		    IS_SET( SysInfo->flags, SYSINFO_REBOOT )
		    ? "reboot" : "shutdown" );
	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s removed autoreboot/shutdown.", rch->name );
    }

    return;
}


/*
 * Modifications contributed by
 * Canth (phule@xs4all.nl)
 * Maniac (v942346@si.hhs.nl)
 * Vego (v942429@si.hhs.nl)
 */
void do_imtlset( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg1[MAX_INPUT_LENGTH];
    char buf[MAX_STRING_LENGTH];
    char buf1[MAX_STRING_LENGTH];
    bool fAll = FALSE;
    int cmd;
    int col = 0;

    rch = get_char( ch );

    if( !authorized( rch, "imtlset" ) )
	return;

    argument = one_argument( argument, arg1 );

    if( arg1[0] == '\0' )
    {
	send_to_char( "Syntax: imtlset <victim> +|- <immortal skill>\n\r", ch );
	send_to_char( "or:     imtlset <victim> +|- all\n\r", ch );
	send_to_char( "or:     imtlset <victim>\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( rch, arg1 ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
    {
	send_to_char( "Not on NPC's.\n\r", ch );
	return;
    }

    if( rch->level <= victim->level && rch != victim )
    {
	send_to_char( "You may not imtlset your peer nor your superior.\n\r",
		     ch );
	return;
    }

    if( argument[0] == '+' || argument[0] == '-' )
    {
	buf[0] = '\0';

	argument = one_argument( argument, arg1 );

	if( !str_cmp( argument, "all" ) )
	{
	    fAll = TRUE;
	}

	if( arg1[0] == '+' )
	{
	    if( !fAll )
	    {
		if( victim->pcdata->immskll )
		    sprintf( buf, "%s", victim->pcdata->immskll );

		if( is_name( argument, victim->pcdata->immskll ) )
		{
		    send_to_char( "That skill has already been set.\n\r", ch );
		    return;
		}

	    }

	    for( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
	    {
		if( cmd_table[cmd].level > get_trust( rch ) )
		    continue;
		if( fAll )
		{
		    if( cmd_table[cmd].level <= get_trust( victim )
			&& cmd_table[cmd].level >= LEVEL_HERO
			&& str_infix(
			    cmd_table[cmd].name,
			    "reboo sla shutdow copyove punload : ] ? <" ) )
		    {
			strcat( buf, cmd_table[cmd].name );
			strcat( buf, " " );
		    }
		}
		else	/* Add only one skill */
		{
		    if( !str_cmp( argument, cmd_table[cmd].name ) )
			break;
		}
	    }

	    if( !fAll )
	    {
		if( cmd_table[cmd].name[0] == '\0'
		    || is_name( argument, "reboo sla shutdow copyove punload : ] ? <" ) )
		{
		    send_to_char( "That is not an immskill.\n\r", ch );
		    return;
		}

		strcat( buf, argument );
		strcat( buf, " " );	/* This line is really not needed but
					 * makes pfile look nice - Kahn */
	    }
	}
	else	    /* arg1[0] == '-' */
	{
	    if( fAll )
	    {
		free_string( victim->pcdata->immskll );
		victim->pcdata->immskll = str_dup( "" );
		send_to_char( "All Immskills have been deleted.\n\r", ch );
		return;
	    }
	    else	/* Remove one skill */
	    {
		const char *buf2 = &buf1[0];
		char arg3[MAX_INPUT_LENGTH];
		char arg2[MAX_INPUT_LENGTH];

		one_argument( argument, arg2 );

		strcpy( buf1, victim->pcdata->immskll );

		if( !is_name( arg2, victim->pcdata->immskll ) )
		{
		    send_to_char( "That Immskill is not set.\n\r", ch );
		    return;
		}

		while( buf2[0] != '\0' )
		{
		    buf2 = one_argument( buf2, arg3 );
		    if( str_cmp( arg3, arg2 ) )
		    {
			strcat( buf, arg3 );
			strcat( buf, " " );
		    }
		}
	    }
	}

	free_string( victim->pcdata->immskll );
	victim->pcdata->immskll = str_dup( buf );

	wiznetf( ch, WIZ_MISC, get_trust( ch ),
		 "%s has set/removed some imm skills for %s.",
		 rch->name, victim->name );
    }

    sprintf( buf, "Immortal skills set for %s:\n\r", victim->name );
    send_to_char( buf, ch );
    buf1[0] = '\0';
    for( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
    {
	if( cmd_table[cmd].level < LEVEL_HERO
	    || !is_name( cmd_table[cmd].name, victim->pcdata->immskll ) )
	    continue;

	sprintf( buf, "%-12s", cmd_table[cmd].name );
	strcat( buf1, buf );
	if( ++col % 6 == 0 )
	    strcat( buf1, "\n\r" );
    }

    if( col % 6 != 0 )
	strcat( buf1, "\n\r" );
    send_to_char( buf1, ch );

    return;
}


void do_grant( CHAR_DATA *ch, const char *argument )
{
    char arg1[MAX_INPUT_LENGTH];
    CHAR_DATA *victim;
    CHAR_DATA *rch;
    int num;

    rch = get_char( ch );
    if( !authorized( rch, "grant" ) )
	return;
    argument = one_argument( argument, arg1 );
    if( argument[0] == '\0' || !is_number( argument ) )
    {
	send_to_char( "Usage: grant <character> <experience>\n\r", ch );
	return;
    }
    if( !( victim = get_char_world( ch, arg1 ) ) )
    {
	send_to_char( "You can't find that person.\n\r", ch );
	return;
    }
    num = atoi_special( argument ) * 100;
    sprintf( arg1, "%s has granted you %d experience!\n\r",
	    ch->name, num / 100 );
    send_to_char( arg1, victim );
    send_to_char( "Ok.\n\r", ch );
    gain_exp( victim, num );
    wiznetf( ch, WIZ_LEVELS, get_trust( ch ),
	     "%s has just granted %s %d experience.",
	     rch->name, victim->name, num / 100 );

    return;
}


void do_avatar( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char buf[MAX_INPUT_LENGTH];
    int num;
    char arg[MAX_INPUT_LENGTH];

    rch = get_char( ch );
    if( !authorized( rch, "avatar" ) )
	return;

    argument = one_argument( argument, arg );
    if( arg[0] != '\0' && !is_number( arg ) )
    {
	send_to_char( "Usage: avatar <level> [special]\n\r", ch );
	return;
    }
    if( arg[0] == '\0' )
    {
	if( ch->level == get_trust( ch ) )
	    num = LEVEL_HERO;
	else
	    num = get_trust( ch );
    }
    else
	num = URANGE( 1, atoi( arg ), get_trust( ch ) );
    sprintf( buf, "You are now level %d!\n\r", num );
    send_to_char( buf, ch );
    if( num != atoi( arg ) )
    {
	send_to_char( " (Note: the range is 1 to your trust level)\n\r", ch );
    }
    ch->level = num;
    if( !str_cmp( argument, "special" ) )
    {
	int i;

	ch->max_hit -= get_max_hit( ch ) - 20;
	for( i = 0; i < MAGIC_MAX; ++i )
	    ch->max_mana[i] -= get_max_mana( ch, i ) - 50
		- class_table[ch->class].fMana;
	ch->max_move -= get_max_move( ch ) - 100;
	ch->practice = 0;
	for( ; num > 1; num-- )
	{
	    advance_level( ch, TRUE );
	}
	ch->hit = ch->max_hit;
	for( i = 0; i < MAGIC_MAX; ++i )
	    ch->mana[i] = ch->max_mana[i];
	ch->move = ch->max_move;
    }
    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s has avatarred to level %d.",
	     ch->name, ch->level );
    return;
}


void do_unaffect( CHAR_DATA *ch, const char *argument )
{
    AFFECT_DATA *paf;
    OBJ_DATA *obj;
    CHAR_DATA *victim;
    CHAR_DATA *rch;

    rch = get_char( ch );
    if( !authorized( rch, "unaffect" ) )
	return;
    if( argument[0] == '\0' )
    {
	send_to_char( "Usage: unaffect <character>\n\r", rch );
	return;
    }
    victim = get_char_world( rch, argument );
    if( !victim || IS_NPC( victim ) )
    {
	send_to_char( "They aren't here.\n\r", rch );
	return;
    }
    for( obj = victim->carrying; obj; obj = obj->next_content )
    {
	if( obj->wear_loc != WEAR_NONE )
	    unequip_char( victim, obj );
    }
    for( paf = victim->affected; paf; paf = paf->next )
    {
	if( paf->deleted )
	    continue;
	affect_remove( victim, paf );
    }
    clean_char( victim );
    victim->body_parts = race_table[victim->race].body_parts;
    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s has cleared %s's affects.",
	     ch->name, victim->name );
    send_to_char( "Your affects have been cleared.\n\r", victim );
    send_to_char( "Ok.\n\r", rch );
    return;
}


void do_masscast( CHAR_DATA *ch, const char *argument )
{
    DESCRIPTOR_DATA *d;
    CHAR_DATA *vch, *rch;
    ROOM_INDEX_DATA *room;
    int sn;

    rch = get_char( ch );
    if( !authorized( rch, "masscast" ) )
	return;

    sn = skill_lookup( argument );
    if( argument[0] == '\0' || sn <= 0 )
    {
	send_to_char( "What spell was that?", ch );
	return;
    }

    if( skill_table[sn].target != TAR_CHAR_DEFENSIVE &&
	skill_table[sn].target != TAR_CHAR_SELF )
    {
	send_to_char( "Defensive spells only please.\n\r", ch );
	return;
    }

    room = ch->in_room;
    char_from_room( ch );
    for( d = descriptor_list; d; d = d->next )
    {
	if( IS_SET( d->interpreter->flags, INTERPRETER_SAFE ) )
	    continue;
	vch = d->character;
	if( vch->deleted || IS_NPC( vch ) || ch == vch )
	    continue;
	if( vch->in_room )
	{
	    char_to_room( ch, vch->in_room );
	    say_spell( ch, sn );
	    char_from_room( ch );
	}
	/* so character doesn't get spammed, the victim casts it on
	   themselves.	    --Symposium */
	SET_BIT( vch->pcdata->pc_bits, PC_BIT_RACIAL );
	( *skill_table[sn].spell_fun )
	    ( sn, rch->level, vch, ( void * )vch );
	REMOVE_BIT( vch->pcdata->pc_bits, PC_BIT_RACIAL );
    }
    char_to_room( ch, room );
    send_to_char( "&gOk.&n\n\r", ch );
    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s masscast the spell %s.",
	     rch->name, skill_table[sn].name );
    return;
}


void bamf( CHAR_DATA *ch )
{
    ROOM_INDEX_DATA *room;

    for( ;; )
    {
	room = get_room_index( number_range( 100, 65536 ) );
	if( room && !IS_SET( room->room_flags, ROOM_PRIVATE )
	    && !IS_SET( room->room_flags, ROOM_SOLITARY )
	    && !IS_SET( room->room_flags, ROOM_NO_PORTAL )
	    && get_trust( ch ) + 5 >= room->area->min
	    && !IS_SET( room->area->area_flags, AREA_HIDE )
	    && room->area->plane == ch->in_room->area->plane )
	    break;
    }
    char_from_room( ch );
    char_to_room( ch, room );
    return;
}


void do_battle( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *bob;
    ROOM_INDEX_DATA *prep_room = get_room_index( ROOM_VNUM_PREP_ROOM );
    char arg1[MAX_INPUT_LENGTH];

    rch = get_char( ch );
    if( argument[0] == '\0' || !authorized( rch, "battle" ) )
    {
	if( ( battle_min == 0 && battle_max == 0 )
	    || rch->level < battle_min || rch->level > battle_max )
	{
	    send_to_char( "Sorry you cannot currently join a battle.\n\r",
			  rch );
	    return;
	}
	char_from_room( rch );
	char_to_room( rch, prep_room );
	do_look( rch, AUTOLOOK );
	return;
    }
    if( !str_cmp( argument, "start" ) )
    {
	if( !prep_room->people || !prep_room->people->next_in_room )
	{
	    send_to_char( "There aren't enough people for a battle.\n\r", ch );
	    if( ( bob = prep_room->people ) )
		char_from_room( bob );
	    char_to_room( bob, get_room_index( ROOM_VNUM_TEMPLE ) );
	    return;
	}
	send_to_all_char( "&gBATTLE started!&n\n\r" );
	for( bob = prep_room->people; bob; bob = prep_room->people )
	{
	    bamf( bob );
	    xSET_BIT( bob->act, PLR_BATTLE );
	}
	return;
    }

    if( IS_SET( SysInfo->flags, SYSINFO_HOLYWAR ) )
    {
	send_to_char( "A Holy War rages at the moment, leave it for a bit.\n\r",
		      ch );
	return;
    }

    argument = one_argument( argument, arg1 );
    if( !is_number( arg1 ) || !is_number( argument ) )
    {
	send_to_char(
	    "Maybe you should specify level limits for the battle.\n\r", ch );
	return;
    }
    battle_min = atoi( arg1 );
    battle_max = atoi( argument );
    if( battle_min > 0 && battle_max > 0 && battle_min < LEVEL_IMMORTAL
	&& battle_max < LEVEL_IMMORTAL )
    {
	sprintf( arg1, "&Y%s has opened a battle for levels %d to %d!&n\n\r",
		rch->name, battle_min, battle_max );
	send_to_all_char( arg1 );
    }
    else
	send_to_char( "Please make these positive integers!", ch );
    return;
}


/*  Copyover - Original idea: Fusion of MUD++
 *  Adapted to Diku by Erwin S. Andreasen, <erwin@pip.dknet.dk>
 *  http://pip.dknet.dk/~pip1773
 */
void do_copyover( CHAR_DATA *ch, const char *argument )
{
    FILE *fp;
    DESCRIPTOR_DATA *d, *d_next;
    char buf[100], buf2[100];
    CHAR_DATA *rch;

    rch = get_char( ch );
    if( !authorized( rch, "copyover" ) )
	return;

#if defined( WIN32 )
    if( str_cmp( argument, "force" ) )
    {
	send_to_char( "Under windoze, copyover doesn't really work.\n\r", ch );
	send_to_char( "If you want to copyover anyway type: copyover force\n\r", ch );
	return;
    }
#endif

    fp = open_file( COPYOVER_FILE, "w", FALSE );

    if( !fp )
    {
	send_to_char( "Copyover file not writeable, aborted.\n\r", ch );
	log_string( "Could not write to copyover file: %s", COPYOVER_FILE );
	perror( "do_copyover: open_file" );
	return;
    }

    /* save all changed areas, and buried items */
    db_dump( );
#if defined( unix ) && !defined( CYGWIN32 )
    ispell_done( );
#endif

    sprintf( buf, "\n\r <-+| COPYOVER by %s - please remain seated! |+->\n\r",
	     ch->name );

    /* For each playing descriptor, save its state */
    for( d = descriptor_list; d; d = d_next )
    {
	CHAR_DATA *och = CH( d );

	d_next = d->next;

#if defined( MCCP )
	compress_end( d, d->mccp_version );
#endif

	if( !d->character
	    || IS_SET( d->interpreter->flags, INTERPRETER_SAFE ) )
	    /* drop those logging on */
	{
	    write_to_descriptor( d->descriptor,
				 "\n\rSorry, we are rebooting. "
				 "Come back in a few minutes.\n\r", 0 );
	    close_socket( d );
	}
	else
	{
	    fprintf( fp, "%d %s %s\n", d->descriptor, och->name, d->host );
	    if( och->level == 1 )
	    {
		write_to_descriptor(
		    d->descriptor,
		    "Since you are level one, and level one characters do "
		    "not save...\n\r\tYou gain a free level!\n\r", 0 );
		advance_level( och, TRUE );
		och->level++;
	    }
	    save_char_obj( och );

	    write_to_descriptor( d->descriptor, buf, 0 );
	}
    }

    fprintf( fp, "-1\n" );
    close_file( fp );

    /* Close reserve and other always-open files and release other resources */
    fclose( fpReserve );
    fpReserve = NULL;

    /* "copyover" put the new file in so it will execute, save the old one */
#if defined( EXE_COPYOVER ) && !defined( WIN32 )
    {
	struct stat tmp;
	if( stat( NEW_EXE_FILE, &tmp ) == 0 )
	{
	    log_string( "Copying the code over." );
	    if( ( unlink( OLD_EXE_FILE ) && errno != ENOENT )
		|| rename( EXE_FILE, OLD_EXE_FILE )
		|| rename( NEW_EXE_FILE, EXE_FILE ) )
	    {
		bug( "Couldn't rename binaries." );
	    }
	}
    }
#endif

    /* execl - descriptors are inherited */
    fflush( stderr );
    sprintf( buf, "%hu", port );
    sprintf( buf2, "%d", control );
    execl( EXE_FILE, "daleken", buf, "copyover", buf2, (char *)NULL );

    /* Failed - sucessful exec will mean this no longer exists */
    perror( "do_copyover: execl" );
    send_to_char( "&RCopyover FAILED!&n\n\r", ch );

    /* Here you might want to reopen fpReserve */
    fpReserve = fopen( NULL_FILE, "r" );
    return;
}


void do_copyove( CHAR_DATA *ch, const char *argument )
{
    send_to_char( "If you want to COPYOVER, spell it out.\n\r", ch );
    return;
}


void do_nolag( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    char arg[MAX_INPUT_LENGTH];
    bool on;

    rch = get_char( ch );

    if( !authorized( rch, "nolag" ) )
	return;

    argument = one_argument( argument, arg );
    if( argument[0] == '\0' )
    {
	victim = ch;
    }
    else if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "Usage: nolag <on/off> <victim>\n\r", ch );
	return;
    }

    if( IS_NPC( victim ) )
	return;

    if( !str_cmp( arg, "on" ) )
	on = TRUE;
    else if( !str_cmp( arg, "off" ) )
	on = FALSE;
    else if( xIS_SET( victim->act, PLR_NO_LAG ) )
	on = FALSE;
    else
	on = TRUE;

    if( on )
    {
	xSET_BIT( victim->act, PLR_NO_LAG );
	if( victim == ch )
	    send_to_char( "You no longer get lagged.\n\r", ch );
	else
	    send_to_char( "They no longer get lagged.\n\r", ch );
    }
    else
    {
	xREMOVE_BIT( victim->act, PLR_NO_LAG );
	if( victim == ch )
	    send_to_char( "You now lag normally.\n\r", ch );
	else
	    send_to_char( "They now lag normally.\n\r", ch );
    }
    return;
}


void do_send( CHAR_DATA *ch, const char *argument )
{
    char arg1[MAX_INPUT_LENGTH];
    CHAR_DATA *victim = NULL;
    CHAR_DATA *rch;
    DESCRIPTOR_DATA *d;
    SOCKET desc_num = 0;

    rch = get_char( ch );
    if( !authorized( rch, "send" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Usage: send <character> <message>\n\r", ch );
	return;
    }

    argument = one_argument( argument, arg1 );

    if( is_number( arg1 ) )
    {
	desc_num = (SOCKET)atoi( arg1 );
    }
    else
    {
	if( !( victim = get_char_world( ch, arg1 ) ) )
	{
	    send_to_char( "You can't find that person.\n\r", ch );
	    return;
	}
    }

    for( d = descriptor_list; d; d = d->next )
    {
	if( d->descriptor == desc_num || ( victim && d == victim->desc ) )
	{
	    if( victim && get_trust( victim ) >= get_trust( ch ) )
		act( "&b$N has just sent you the message:",
		     victim, NULL, ch, TO_CHAR );
	    write_to_buffer( d, argument );
	    write_to_buffer( d, "\n\r" );
	    return;
	}
    }

    return;
}


void do_keylock( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );
    if( !authorized( rch, "keylock" ) )
	return;

    send_to_char( "Ok, keylocking your character.\n\r", ch );
    send_to_char( "You will have to enter your password to unlock input.\n\r", ch );
    xSET_BIT( rch->act, PLR_KEYLOCK );
    return;
}


/*
 * This is a _very_ expensive function in terms of time.
 * Luckily we don't use it too often, I hope!
 *		-- Symposium
 */
void do_dupefind( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    OBJ_DATA *obj, *dobj, *in_obj;
    int count = 0;
    char buf[ 40 ];

    if( ch )
	rch = get_char( ch );
    if( ch && !authorized( rch, "dupefind" ) )
	return;

    /* Turn of the CPU time alarm for this function. */
    SET_BIT( SysInfo->flags, SYSINFO_NOCPULIMIT );

    for( obj = object_list; obj; obj = obj->next )
    {
	if( obj->deleted )
	    continue;
	for( dobj = obj->next; dobj; dobj = dobj->next )
	{
	    if( obj->unique_key == dobj->unique_key
		&& obj->pIndexData == dobj->pIndexData
		&& !dobj->deleted )
	    {
		count++;
		log_string( "Item duplication (key %d):", obj->unique_key );

		for( in_obj = obj; in_obj && in_obj->in_obj;
		     in_obj = in_obj->in_obj )
		    ;
		if( in_obj->carried_by )
		    log_string( "-- %s&n carried by %s.",
			       obj->short_descr, in_obj->carried_by->name );
		else
		    log_string( "-- %s&n in %s&n.",
			       obj->short_descr, !in_obj->in_room
			       ? "somewhere" : in_obj->in_room->name );

		for( in_obj = dobj; in_obj && in_obj->in_obj;
		     in_obj = in_obj->in_obj )
		    ;
		if( in_obj->carried_by )
		    log_string( "-- %s&n carried by %s&n.",
			       dobj->short_descr, in_obj->carried_by->name );
		else
		    log_string( "-- %s&n in %s&n.",
			       dobj->short_descr, !in_obj->in_room
			       ? "somewhere" : in_obj->in_room->name );

	    }
	}
    }
    if( ch )
    {
	sprintf( buf, "%d duplications found.\n\r", count );
	send_to_char( buf, ch );
    }

    /* Turn of the CPU time alarm for this function. */
    REMOVE_BIT( SysInfo->flags, SYSINFO_NOCPULIMIT );

    return;
}


void do_info( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );
    if( !authorized( rch, "info" ) )
	return;

    if( !str_cmp( argument, "on" ) || !xIS_SET( rch->act, PLR_INFO ) )
	xSET_BIT( rch->act, PLR_INFO );
    else
	xREMOVE_BIT( rch->act, PLR_INFO );
    if( xIS_SET( rch->act, PLR_INFO ) )
	send_to_char( "You will now see additional game info.\n\r", ch );
    else
	send_to_char( "You now wont see additional info.\n\r", ch );
    return;
}


void do_nofight( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );
    if( !authorized( rch, "nofight" ) )
	return;

    TOGGLE_BIT( SysInfo->flags, SYSINFO_NOFIGHT );

    if( IS_SET( SysInfo->flags, SYSINFO_NOFIGHT ) )
	send_to_char( "Game no_fighted.\n\r", ch );
    else
	send_to_char( "Game un-no_fighted.\n\r", ch );

    wiznetf( ch, WIZ_MISC, get_trust( ch ), "%s setting nofight to %sE.",
	     ch->name, IS_SET( SysInfo->flags, SYSINFO_NOFIGHT )
	     ? "TRU" : "FALS" );
    return;
}


#ifndef INT_MAX
#define INT_MAX 65536
#endif
void do_builder( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    AREA_DATA *pArea;
    char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];
    int lower, upper;

    rch = get_char( ch );
    if( !authorized( rch, "builder" ) )
	return;

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );
    if( !( victim = get_char_room( ch, arg1 ) ) || IS_NPC( victim ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( get_trust( victim ) > L_HER )
    {
	send_to_char( "They are too high level for you to make builder.\n\r",
		      ch );
	return;
    }

    if( !str_cmp( arg2, "newarea" ) )
    {
	if( rch->pcdata->security < 2 )
	{
	    send_to_char( "You can't create an area.\n\r", ch );
	    return;
	}

	argument = one_argument( argument, arg1 );
	one_argument( argument, arg2 );
	if( arg1[0] == '\0' || arg2[0] == '\0'
	    || !is_number( arg1 ) || !is_number( arg2 ) )
	{
	    send_to_char( "<lvnum> and <uvnum> must be numbers.\n\r", ch );
	    return;
	}
	lower = atoi( arg1 );
	upper = atoi( arg2 );
	if( lower > upper || lower <= 0 || lower >= INT_MAX
	    || upper <= 0 || upper >= INT_MAX )
	{
	    send_to_char( "Invalid number range.\n\r", ch );
	    return;
	}
	if( get_vnum_area( lower ) || get_vnum_area( upper ) )
	{
	    send_to_char( "Range includes another area.\n\r", ch );
	    return;
	}

	pArea = new_area( );
	area_last->next = pArea;
	area_last = pArea;
	SET_BIT( pArea->area_flags, AREA_ADDED );
	pArea->security = rch->pcdata->security;
	pArea->lvnum = lower;
	pArea->uvnum = upper;
	pArea->builders = str_dup( victim->name );
	pArea->plane = plane_lookup( "unfinished" );

	send_to_char( "Area Created.\n\r", ch );
    }
    victim->class = CLASS_BUILDER;
    victim->trust = L_BLD;
    victim->pcdata->immskll = str_dup( "aedit redit medit oedit resets "
				       "alist asave goto purge wizhelp "
				       "holylight immtalk flagloookup" );
    victim->pcdata->security = 1;

    send_to_char( "Ok.\n\r", ch );
    return;
}


/*
 *  Wiznet 0.1 improvements copyright (C) 1996 by The Maniac.
 *  Written by The Maniac from Mythran Mud.
 */
void do_wiznet( CHAR_DATA* ch, const char *argument )
{
    char arg[ MAX_STRING_LENGTH ];
    CHAR_DATA * rch;
    int trust;

    rch = get_char( ch );

    if( !authorized( rch, "wiznet" ) )
	return;

    one_argument( argument, arg );

    trust = get_trust( ch );
    if( arg[0] == '\0' )
    {
	send_to_char( "[ Keyword  ] Option\n\r", ch );

	send_to_char( IS_SET( rch->deaf, WIZ_ON )
		      ? "[+WIZNET   ] Wiznet is on.\n\r"
		      : "[-wiznet   ] Wiznet is off.\n\r"
		      , ch );
	if( trust >= L_OVL )
	    send_to_char( IS_SET( rch->deaf, WIZ_LOG )
			  ? "[+LOGS     ] You see logged strings.\n\r"
			  : "[-logs     ] You don't see logged strings.\n\r"
			  , ch );
	send_to_char( IS_SET( rch->deaf, WIZ_LOGINS )
		      ? "[+LOGINS   ] You are notified of logins.\n\r"
		      : "[-logins   ] You aren't notified of logins.\n\r"
		      , ch );
	send_to_char( IS_SET( rch->deaf, WIZ_DEATHS )
		      ? "[+DEATHS   ] You are notified of deaths.\n\r"
		      : "[-deaths   ] You aren't notified of deaths.\n\r"
		      , ch );
	send_to_char( IS_SET( rch->deaf, WIZ_LEVELS )
		      ? "[+LEVELS   ] You are notified when a player levels.\n\r"
		      : "[-levels   ] You aren't notified when a player levels.\n\r"
		      , ch );
	send_to_char( IS_SET( rch->deaf, WIZ_TICKS )
		      ? "[+TICKS    ] You see are notified of ticks.\n\r"
		      : "[-ticks    ] You aren't notified of ticks.\n\r"
		      , ch );
	if( trust >= L_SEN )
	    send_to_char( IS_SET( rch->deaf, WIZ_COMMANDS )
			  ? "[+COMMANDS ] You see logged commands.\n\r"
			  : "[-commands ] You don't see logged commands.\n\r"
			  , ch );
	if( trust >= L_JUN )
	    send_to_char( IS_SET( rch->deaf, WIZ_MISC )
			  ? "[+MISC     ] Wiznet miscellaneous info is on.\n\r"
			  : "[-misc     ] Wiznet miscellaneous info is off.\n\r"
			  , ch );
	if( trust >= L_JUN )
	    send_to_char( IS_SET( rch->deaf, WIZ_CLAN )
			  ? "[+CLAN     ] Clan/religion messages are on.\n\r"
			  : "[-clan     ] Clan/religion messages are off.\n\r"
			  , ch );
	if( trust >= L_SEN )
	    send_to_char( IS_SET( rch->deaf, WIZ_CREATE )
			  ? "[+CREATE   ] Wiznet on creation is on.\n\r"
			  : "[-create   ] Wiznet on creation is off.\n\r"
			  , ch );
	if( trust >= L_MAS )
	    send_to_char( IS_SET( rch->deaf, WIZ_DEBUG )
			  ? "[+DEBUG    ] Wiznet debug is on.\n\r"
			  : "[-debug    ] Wiznet debug is off.\n\r"
			  , ch );
    }
    else
    {
	char buf [ MAX_INPUT_LENGTH ];
	int  bit;
	bool fSet;

	if( arg[0] == '+' ) fSet = TRUE;
	else if( arg[0] == '-' ) fSet = FALSE;
	else
	{
	    send_to_char( "Wiznet: config -option or +option?\n\r", ch );
	    return;
	}

	if( !str_cmp( arg+1, "wiznet"	) ) bit = WIZ_ON;
	else if( !str_cmp( arg+1, "logs"	) ) bit = WIZ_LOG;
	else if( !str_cmp( arg+1, "logins"	) ) bit = WIZ_LOGINS;
	else if( !str_cmp( arg+1, "deaths"	) ) bit = WIZ_DEATHS;
	else if( !str_cmp( arg+1, "levels"	) ) bit = WIZ_LEVELS;
	else if( !str_cmp( arg+1, "ticks"	) ) bit = WIZ_TICKS;
	else if( !str_cmp( arg+1, "commands"	) ) bit = WIZ_COMMANDS;
	else if( !str_cmp( arg+1, "misc"	) ) bit = WIZ_MISC;
	else if( !str_cmp( arg+1, "create"	) ) bit = WIZ_CREATE;
	else if( !str_cmp( arg+1, "clan"	) ) bit = WIZ_CLAN;
	else if( !str_cmp( arg+1, "debug"	) ) bit = WIZ_DEBUG;
	else if( !str_cmp( arg+1, "ALL"		) )
	{
	    bit = WIZ_ON | WIZ_LOG | WIZ_LOGINS | WIZ_DEATHS | WIZ_LEVELS
		| WIZ_COMMANDS | WIZ_MISC | WIZ_CREATE | WIZ_CLAN
		| WIZ_DEBUG;
	}
	else
	{
	    send_to_char( "Wiznet: config which option?\n\r", ch );
	    return;
	}

	if( fSet )
	{
	    SET_BIT( rch->deaf, bit );
	    sprintf( buf, "%s is now ON.\n\r", arg+1 );
	    buf[0] = UPPER( buf[0] );
	    send_to_char( buf, ch );
	}
	else
	{
	    REMOVE_BIT( rch->deaf, bit );
	    sprintf( buf, "%s is now OFF.\n\r", arg+1 );
	    buf[0] = UPPER( buf[0] );
	    send_to_char( buf, ch );
	}
    }
    return;
}


/*
 * Pload by Erwin Andreasen.
 */
void do_pload( CHAR_DATA *ch, const char *argument )
{
    DESCRIPTOR_DATA d;
    CHAR_DATA *ch_on;
    CHAR_DATA *rch = get_char( ch );
    bool isChar;
    char name[MAX_INPUT_LENGTH];

    if( !authorized( rch, "pload" ) )
	return;

    if( argument[0] == '\0' )
    {
	send_to_char( "Load who?\n\r", ch );
	return;
    }

    argument = one_argument( argument, name );
    name[0] = UPPER( name[0] );

    /* Don't want to load a second copy of a player who's already online! */
    for( ch_on = char_list; ch_on; ch_on = ch_on->next )
    {
	if( !ch_on->deleted && !IS_NPC( ch_on )
	    && !str_cmp( ch_on->name, name ) )
	{
	    send_to_char( "That person is already connected!\n\r", ch );
	    return;
	}
    }

    memset( &d, 0, sizeof( DESCRIPTOR_DATA ) );
    isChar = load_char_obj( &d, name ); /* char pfile exists? */

    if( !isChar )
    {
	send_to_char( "Load Who? Are you sure? I can't seem to find them.\n\r", ch );
	return;
    }

    d.character->desc	= NULL;
    d.character->next	= char_list;
    char_list		= d.character;
    d.interpreter	= get_interpreter( "" );

    /* bring player to imm */
    if( d.character->in_room != NULL )
    {
	if( d.character->was_in_room == NULL )
	    d.character->was_in_room = d.character->in_room;

	d.character->in_room = NULL;
	char_to_room( d.character, ch->in_room);
    }

    charprintf( ch, "You have pulled %s from the pattern!\n\r",
		d.character->name );

    act( "$n has pulled $N from the pattern!",
	 ch, NULL, d.character, TO_ROOM );
    if( !str_cmp( argument, "nosave" ) )
	xSET_BIT( d.character->act, PLR_NOSAVE );

    return;
}


void do_punload( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *victim;
    CHAR_DATA *rch = get_char( ch );

    if( !authorized( rch, "pload" ) )
	return;

    if( ( victim = get_char_world( ch, argument ) ) == NULL )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    /** Person is legitimately logged on... was not ploaded.
     */
    if( victim->desc != NULL )
    {
	send_to_char( "I don't think that would be a good idea...\n\r", ch );
	return;
    }

    if( victim->was_in_room != NULL ) /* return player to orig room */
    {
	char_from_room( victim );
	char_to_room( victim, victim->was_in_room );

	ch->was_in_room = NULL;
    }

    act( "You have released $N back to the Pattern.",
	 ch, NULL, victim, TO_CHAR );
    act( "$n has released $N back to the Pattern.",
	 ch, NULL, victim, TO_ROOM );

    do_quit( victim, "" );
    return;
}


/*
 * Send command output to a file.
 * Known problem: if there are too many people logged on to the MUD
 * and there are no descriptors left this wont work, I didn't consider
 * that to be a significant problem as this command isn't critical.
 * -- Symposium
 */
#if !defined( WIN32 )
void do_fileoutput( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    char *p;
    char file[MAX_INPUT_LENGTH];
    int fd;
    bool colour = FALSE;
    int pagelen;

    rch = get_char( ch );
    if( !ch->desc || !authorized( rch, "fileoutput" ) )
	return;

    argument = one_argument( argument, file );
    for( p = &file[0]; p && *p; ++p )
	if( !isalnum( *p ) )
	{
	    send_to_char( "You can't use shell characters, try again.\n\r",
			  ch );
	    return;
	}
    if( ( fd = open( file, O_RDWR | O_CREAT | O_APPEND | O_NDELAY,
		     S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH ) ) < 0 )
    {
	perror( "FileOutput: couldn't open file" );
	send_to_char( "Couldn't open the file, sorry.\n\r", ch );
	return;
    }

    pagelen = rch->pcdata->pagelen;
    rch->pcdata->pagelen = -99;
    if( xIS_SET( rch->act, PLR_COLOUR ) )
    {
	colour = TRUE;
	xREMOVE_BIT( rch->act, PLR_COLOUR );
    }

    interpret( ch, argument );
    if( !write_to_descriptor( fd, ch->desc->outbuf, ch->desc->outtop ) )
    {
	perror( "FileOutput: writing to descriptor" );
	send_to_char( "Error writing file.\n\r", ch );
    }

    /*
     * maybe someone will write the win32 code for this,
     * all it needs is the file open line to work.
     */
#if !defined( WIN32 )
    if( close( fd ) < 0 )
#else
    if( closesocket( fd ) < 0 )
#endif
	perror( "FileOutput: closing descriptor" );

    rch->pcdata->pagelen = pagelen;
    if( colour )
	xSET_BIT( rch->act, PLR_COLOUR );
    return;
}
#else
void do_fileoutput( CHAR_DATA *ch, const char *argument )
{
    send_to_char( "Fileoutput isn't available on this platform.\n\r", ch );
    return;
}
#endif


/* Expand the name of a character into a string that identifies THAT
      character within a room. E.g. the second 'guard' -> 2. guard */
const char *name_expand( char *outbuf, CHAR_DATA *ch )
{
    int count = 1;
    CHAR_DATA *rch;
    char name[MAX_INPUT_LENGTH]; /* HOPEFULLY no mob has a name longer than THAT */

    if( !IS_NPC( ch ) )
	return ch->name;

    one_argument( ch->name, name ); /* copy the first word into name */

    if( !name[0] ) /* weird mob .. no keywords */
    {
	strcpy( outbuf, "" ); /* Do not return NULL, just an empty buffer */
	return outbuf;
    }

    for( rch = ch->in_room->people; rch && ( rch != ch );
	 rch = rch->next_in_room )
	if( is_char_name( rch, name ) )
	    count++;

    sprintf( outbuf, "%d.%s", count, name );
    return outbuf;
}


/*
 * For/Repeat by Erwin S. Andreasen (4u2@aabc.dk)
 * renamed to repeat to avoid name pollution
 */
void do_repeat( CHAR_DATA *ch, const char *argument )
{
    char range[MAX_INPUT_LENGTH];
    char buf[MAX_STRING_LENGTH];
    bool
	fGods = FALSE,
	fMortals = FALSE,
	fMobs = FALSE,
	fEverywhere = FALSE,
	found;
    ROOM_INDEX_DATA *room, *old_room;
    CHAR_DATA *p, *p_next;
    int i;

    if( !authorized( ch, "repeat" ) )
	return;

    argument = one_argument( argument, range );

    if( !range[0] || !argument[0] ) /* invalid usage? */
    {
	do_help( ch, "repeat" );
	return;
    }

    if( !str_prefix( "quit", argument ) )
    {
	send_to_char( "Are you trying to crash the MUD or something?\n\r",ch );
	return;
    }

    if( !str_cmp( range, "all" ) )
    {
	fMortals = TRUE;
	fGods = TRUE;
    }
    else if( !str_cmp( range, "gods" ) )
	fGods = TRUE;
    else if( !str_cmp( range, "mortals" ) )
	fMortals = TRUE;
    else if( !str_cmp( range, "mobs" ) )
	fMobs = TRUE;
    else if( !str_cmp( range, "everywhere" ) )
	fEverywhere = TRUE;
    else
    {
	do_help( ch, "repeat" );
	return;
    }

    /* do not allow # to make it easier */
    /* Don't allow it, it causes crashes on 'for mobs tell # hi' Maniac */
    if( fEverywhere && strchr( argument, '#' ) )
    {
	send_to_char( "Cannot use FOR EVERYWHERE with the # thingie.\n\r",ch );
	return;
    }

    if( fMobs && strchr( argument, '#' ) )
    {
	send_to_char( "Cannot use FOR MOBS with the # thingie.\n\r",ch );
	return;
    }

    if( strchr( argument, '#' ) ) /* replace # ? */
    {
	for( p = char_list; p; p = p_next )
	{
	    p_next = p->next; /* In case someone DOES try to AT MOBS SLAY # */

	    if( !( p->in_room ) || room_is_private( p->in_room )
		|| ( p == ch ) )
		continue;

	    if( IS_NPC( p ) && fMobs )
		found = TRUE;
	    else if( !IS_NPC( p ) && fGods
		     && get_trust( p ) >= LEVEL_IMMORTAL )
		found = TRUE;
	    else if( !IS_NPC( p ) && fMortals
		     && get_trust( p ) < LEVEL_IMMORTAL )
		found = TRUE;
	    else
		found = FALSE;

	    /* It looks ugly to me.. but it works : ) */
	    if( found )
	    {
		const char *pSource = argument; /* buffer to be parsed */
		char *pDest = buf;		/* parse into this */

		while( *pSource )
		{
		    if( *pSource == '#' ) /* Replace # with name of target */
		    {
			char tmp[MAX_INPUT_LENGTH];
			const char *namebuf = name_expand( tmp, p );

			if( namebuf )
			    while( *namebuf ) /* copy name over */
				*pDest++ = *namebuf++;

			pSource++;
		    }
		    else
			*pDest++ = *pSource++;
		}
		*pDest = '\0';

		/* Execute */
		old_room = ch->in_room;
		char_from_room( ch );
		char_to_room( ch, p->in_room );
		interpret( ch, buf );
		char_from_room( ch );
		char_to_room( ch, old_room );
	    }
	}
    }
    else /* just for every room with the appropriate people in it */
    {
	for( i = 0; i < MAX_KEY_HASH; i++ )
	    for( room = room_index_hash[i] ; room ; room = room->next )
	    {
		found = FALSE;
		if( fEverywhere ) /* Everywhere executes always */
		    found = TRUE;
		else if( !room->people ) /* Skip it if room is empty */
		    continue;

		/* Check if there is anyone here of the requried type
		 * Stop as soon as a match is found or there are no more
		 * ppl in room
		 */
		for( p = room->people; p && !found; p = p->next_in_room )
		{
		    if( p == ch ) /* do not execute on oneself */
			continue;

		    if( IS_NPC( p ) && fMobs )
			found = TRUE;
		    else if( !IS_NPC( p ) && fGods
			     && get_trust( p ) >= LEVEL_IMMORTAL )
			found = TRUE;
		    else if( !IS_NPC( p ) && fMortals
			     && get_trust( p ) < LEVEL_IMMORTAL )
			found = TRUE;
		}

		/* Any of the required type here AND room not private? */
		if( found && !room_is_private( room ) )
		{
		    /* This may be ineffective. Consider moving character out
		     * of old_room once at beginning of command then moving
		     * back at the end.
		     * This however, is more safe?
		     */

		    old_room = ch->in_room;
		    char_from_room( ch );
		    char_to_room( ch, room );
		    interpret( ch, argument );
		    char_from_room( ch );
		    char_to_room( ch, old_room );
		}
	    } /* for every room in a bucket */
    }
    return;
}


void do_wsave( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );
    if( !authorized( rch, "wsave" ) )
	return;

    send_to_char( "Saving all game databases.\n\r", ch );
    db_dump();
    send_to_char( "Done.\n\r", ch );
    return;
}


/*
 * Confiscate an item from a character, whether they are wearing it or not.
 */
void do_confiscate( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;
    CHAR_DATA *victim;
    OBJ_DATA *obj;
    char arg[MAX_INPUT_LENGTH];

    rch = get_char( ch );
    if( !authorized( rch, "confiscate" ) )
	return;

    argument = one_argument( argument, arg );

    if( arg[0] == '\0' || argument[0] == '\0' )
    {
	send_to_char( "Confiscate what from whom?\n\r", ch );
	return;
    }

    if( !( victim = get_char_world( ch, argument ) ) )
    {
	send_to_char( "They aren't here.\n\r", ch );
	return;
    }

    if( victim == ch )
    {
	send_to_char( "Why bother, feel you aren't in control?\n\r", ch );
	return;
    }

    if( get_trust( victim ) >= get_trust( ch ) )
    {
	send_to_char( "Maybe if you asked nicely...\n\r", ch );
	return;
    }

    if( !( obj = get_obj_list( ch, arg, victim->carrying ) ) )
    {
	send_to_char( "They aren't carrying such an item.\n\r", ch );
	return;
    }

    if( can_see( victim, ch ) )
	act( "$p has been confiscated by $N!", victim, obj, ch, TO_CHAR );

    obj_from_char( obj );
    obj_to_char( obj, ch );
    send_to_char( "Yoink!\n\r", ch );
    return;
}


/*
 * Debugging function, put stuff here.
 */
void do_test( CHAR_DATA *ch, const char *argument )
{
    CHAR_DATA *rch;

    rch = get_char( ch );
    if( !authorized( rch, "test" ) )
	return;

    send_to_char( "You test the MUD code.\n\r", ch );
    rch = get_char_room( ch, argument );
    damage( rch, ch, 0, TYPE_HIT, WEAR_WIELD_R );
    return;
}