1stMUD/corefiles/
1stMUD/gods/
1stMUD/player/
1stMUD/win32/
1stMUD/win32/ROM/
/**************************************************************************
*  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
*  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
*                                                                         *
*  Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael         *
*  Chastain, Michael Quan, and Mitchell Tse.                              *
*                                                                         *
*  In order to use any part of this Merc Diku Mud, you must comply with   *
*  both the original Diku license in 'license.doc' as well the Merc       *
*  license in 'license.txt'.  In particular, you may not remove either of *
*  these copyright notices.                                               *
*                                                                         *
*  Much time and thought has gone into this software and you are          *
*  benefiting.  We hope that you share your changes too.  What goes       *
*  around, comes around.                                                  *
***************************************************************************
*       ROM 2.4 is copyright 1993-1998 Russ Taylor                        *
*       ROM has been brought to you by the ROM consortium                 *
*           Russ Taylor (rtaylor@hypercube.org)                           *
*           Gabrielle Taylor (gtaylor@hypercube.org)                      *
*           Brian Moore (zump@rom.org)                                    *
*       By using this code, you have agreed to follow the terms of the    *
*       ROM license, in the file Rom24/doc/rom.license                    *
***************************************************************************
*       1stMUD ROM Derivative (c) 2001-2002 by Ryan Jennings              *
*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
***************************************************************************/

#include <sys/types.h>
#if !defined(WIN32)
#include <sys/time.h>
#include <unistd.h>
#else
#include <io.h>
#include <process.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "interp.h"
#include "recycle.h"
#include "tables.h"
#include "lookup.h"
#include "telnet.h"
#if defined(WIN32)
#include "../win32/winstuff.h"
#endif

/*
 * Local functions.
 */
ROOM_INDEX_DATA *find_location args ((CHAR_DATA * ch, const char *arg));

CH_CMD (do_wiznet)
{
	flag_t flag;
	char buf[MAX_STRING_LENGTH];

	if (argument[0] == '\0')
	{
		if (IS_SET (ch->wiznet, WIZ_ON))
		{
			chprintln (ch, "Signing off of Wiznet.");
			REMOVE_BIT (ch->wiznet, WIZ_ON);
		}
		else
		{
			chprintln (ch, "Welcome to Wiznet!");
			SET_BIT (ch->wiznet, WIZ_ON);
		}
		return;
	}

	if (!str_prefix (argument, "on"))
	{
		chprintln (ch, "Welcome to Wiznet!");
		SET_BIT (ch->wiznet, WIZ_ON);
		return;
	}

	if (!str_prefix (argument, "off"))
	{
		chprintln (ch, "Signing off of Wiznet.");
		REMOVE_BIT (ch->wiznet, WIZ_ON);
		return;
	}

	/* show wiznet status */
	if (!str_prefix (argument, "status"))
	{
		buf[0] = '\0';

		if (!IS_SET (ch->wiznet, WIZ_ON))
			strcat (buf, "off ");

		for (flag = 0; wiznet_table[flag].name != NULL; flag++)
			if (IS_SET (ch->wiznet, wiznet_table[flag].flag))
			{
				strcat (buf, wiznet_table[flag].name);
				strcat (buf, " ");
			}

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

		chprintln (ch, "Wiznet status:");
		chprint (ch, buf);
		return;
	}

	if (!str_prefix (argument, "show"))
		/* list of all wiznet options */
	{
		buf[0] = '\0';

		for (flag = 0; wiznet_table[flag].name != NULL; flag++)
		{
			if (wiznet_table[flag].level <= get_trust (ch))
			{
				strcat (buf, wiznet_table[flag].name);
				strcat (buf, " ");
			}
		}

		chprintln (ch, "Wiznet options available to you are:");
		chprintln (ch, buf);
		return;
	}

	flag = wiznet_lookup (argument);

	if (flag == -1 || get_trust (ch) < wiznet_table[flag].level)
	{
		chprintln (ch, "No such option.");
		return;
	}

	if (IS_SET (ch->wiznet, wiznet_table[flag].flag))
	{
		chprintlnf (ch, "You will no longer see %s on wiznet.",
					wiznet_table[flag].name);
		REMOVE_BIT (ch->wiznet, wiznet_table[flag].flag);
		return;
	}
	else
	{
		chprintlnf (ch, "You will now see %s on wiznet.",
					wiznet_table[flag].name);
		SET_BIT (ch->wiznet, wiznet_table[flag].flag);
		return;
	}

}

void wiznet (char *string, CHAR_DATA * ch, OBJ_DATA * obj, flag_t flag,
			 flag_t flag_skip, int min_level)
{
	DESCRIPTOR_DATA *d;

	for (d = descriptor_list; d != NULL; d = d->next)
	{
		if (d->connected == CON_PLAYING && IS_IMMORTAL (d->character) &&
			IS_SET (d->character->wiznet, WIZ_ON) && (!flag ||
													  IS_SET
													  (d->character->wiznet,
													   flag))
			&& (!flag_skip || !IS_SET (d->character->wiznet, flag_skip))
			&& get_trust (d->character) >= min_level && d->character != ch)
		{
			chprint (d->character, CTAG (_WIZNET));
			if (IS_SET (d->character->wiznet, WIZ_PREFIX))
				chprint (d->character, "--> ");
			act_new (string, d->character, obj, ch, TO_CHAR, POS_DEAD);
		}
	}

	return;
}

CH_CMD (do_guild)
{
	char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	int clan;

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

	if (arg1[0] == '\0' || arg2[0] == '\0')
	{
		chprintln (ch, "Syntax: guild <char> <cln name>");
		return;
	}
	if ((victim = get_char_world (ch, arg1)) == NULL)
	{
		chprintln (ch, "They aren't playing.");
		return;
	}

	if (!str_prefix (arg2, "none"))
	{
		chprintln (ch, "They are now clanless.");
		chprintln (victim, "You are now a member of no clan!");
		victim->clan = -1;
		return;
	}

	if ((clan = clan_lookup (arg2)) == -1)
	{
		chprintln (ch, "No such clan exists.");
		return;
	}

	if (clan_table[clan].independent)
	{
		chprintlnf (ch, "They are now a %s.", clan_table[clan].name);
		chprintlnf (victim, "You are now a %s.", clan_table[clan].name);
	}
	else
	{
		chprintlnf (ch, "They are now a member of clan %s.",
					capitalize (clan_table[clan].name));
		chprintlnf (victim, "You are now a member of clan %s.\n\r",
					capitalize (clan_table[clan].name));
	}

	victim->clan = clan;
}

/* equips a character */
CH_CMD (do_outfit)
{
	OBJ_DATA *obj;
	int i, sn;
	vnum_t vnum;

	if (ch->level > 5 || IS_NPC (ch))
	{
		chprintln (ch, "Find it yourself!");
		return;
	}

	if ((obj = get_eq_char (ch, WEAR_LIGHT)) == NULL)
	{
		obj = create_object (get_obj_index (OBJ_VNUM_SCHOOL_BANNER), 0);
		obj->cost = 0;
		obj_to_char (obj, ch);
		equip_char (ch, obj, WEAR_LIGHT);
	}

	if ((obj = get_eq_char (ch, WEAR_BODY)) == NULL)
	{
		obj = create_object (get_obj_index (OBJ_VNUM_SCHOOL_VEST), 0);
		obj->cost = 0;
		obj_to_char (obj, ch);
		equip_char (ch, obj, WEAR_BODY);
	}

	/* do the weapon thing */
	if ((obj = get_eq_char (ch, WEAR_WIELD)) == NULL)
	{
		sn = 0;
		vnum = OBJ_VNUM_SCHOOL_SWORD;	/* just in case! */

		for (i = 0; weapon_table[i].name != NULL; i++)
		{
			if (ch->pcdata->learned[sn] <
				ch->pcdata->learned[*weapon_table[i].gsn])
			{
				sn = *weapon_table[i].gsn;
				vnum = weapon_table[i].vnum;
			}
		}

		obj = create_object (get_obj_index (vnum), 0);
		obj_to_char (obj, ch);
		equip_char (ch, obj, WEAR_WIELD);
	}

	if (((obj = get_eq_char (ch, WEAR_WIELD)) == NULL ||
		 !IS_WEAPON_STAT (obj, WEAPON_TWO_HANDS)) &&
		(obj = get_eq_char (ch, WEAR_SHIELD)) == NULL)
	{
		obj = create_object (get_obj_index (OBJ_VNUM_SCHOOL_SHIELD), 0);
		obj->cost = 0;
		obj_to_char (obj, ch);
		equip_char (ch, obj, WEAR_SHIELD);
	}

	chprintln (ch, "You have been equipped by Mota.");
}

/* RT nochannels command, for those spammers */
CH_CMD (do_nochannels)
{
	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Nochannel whom?");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (get_trust (victim) >= get_trust (ch))
	{
		chprintln (ch, "You failed.");
		return;
	}

	if (IS_SET (victim->comm, COMM_NOCHANNELS))
	{
		REMOVE_BIT (victim->comm, COMM_NOCHANNELS);
		chprintln (victim, "The gods have restored your channel priviliges.");
		chprintln (ch, "NOCHANNELS removed.");
		sprintf (buf, "$N restores channels to %s", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}
	else
	{
		SET_BIT (victim->comm, COMM_NOCHANNELS);
		chprintln (victim, "The gods have revoked your channel priviliges.");
		chprintln (ch, "NOCHANNELS set.");
		sprintf (buf, "$N revokes %s's channels.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}

	return;
}

CH_CMD (do_smote)
{
	CHAR_DATA *vch;
	const char *letter, *name;
	char last[MAX_INPUT_LENGTH], temp[MAX_STRING_LENGTH];
	unsigned int matches = 0;

	if (!IS_NPC (ch) && IS_SET (ch->comm, COMM_NOEMOTE))
	{
		chprintln (ch, "You can't show your emotions.");
		return;
	}

	if (argument[0] == '\0')
	{
		chprintln (ch, "Emote what?");
		return;
	}

	if (strstr (argument, ch->name) == NULL)
	{
		chprintln (ch, "You must include your name in an smote.");
		return;
	}

	chprintln (ch, argument);

	for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
	{
		if (vch->desc == NULL || vch == ch)
			continue;

		if ((letter = strstr (argument, vch->name)) == NULL)
		{
			chprintln (vch, argument);
			continue;
		}

		strcpy (temp, argument);
		temp[strlen (argument) - strlen (letter)] = '\0';
		last[0] = '\0';
		name = vch->name;

		for (; *letter != '\0'; letter++)
		{
			if (*letter == '\'' && matches == strlen (vch->name))
			{
				strcat (temp, "r");
				continue;
			}

			if (*letter == 's' && matches == strlen (vch->name))
			{
				matches = 0;
				continue;
			}

			if (matches == strlen (vch->name))
			{
				matches = 0;
			}

			if (*letter == *name)
			{
				matches++;
				name++;
				if (matches == strlen (vch->name))
				{
					strcat (temp, "you");
					last[0] = '\0';
					name = vch->name;
					continue;
				}
				strncat (last, letter, 1);
				continue;
			}

			matches = 0;
			strcat (temp, last);
			strncat (temp, letter, 1);
			last[0] = '\0';
			name = vch->name;
		}

		chprintln (vch, temp);
	}

	return;
}

CH_CMD (do_bamfin)
{

	if (!IS_NPC (ch))
	{
		smash_tilde (argument);

		if (argument[0] == '\0')
		{
			chprintlnf (ch, "Your poofin is %s", ch->pcdata->bamfin);
			return;
		}

		if (strstr (argument, ch->name) == NULL)
		{
			chprintln (ch, "You must include your name.");
			return;
		}

		free_string (ch->pcdata->bamfin);
		ch->pcdata->bamfin = str_dup (argument);

		chprintlnf (ch, "Your poofin is now %s", ch->pcdata->bamfin);
	}
	return;
}

CH_CMD (do_bamfout)
{

	if (!IS_NPC (ch))
	{
		smash_tilde (argument);

		if (argument[0] == '\0')
		{
			chprintlnf (ch, "Your poofout is %s", ch->pcdata->bamfout);
			return;
		}

		if (strstr (argument, ch->name) == NULL)
		{
			chprintln (ch, "You must include your name.");
			return;
		}

		free_string (ch->pcdata->bamfout);
		ch->pcdata->bamfout = str_dup (argument);

		chprintlnf (ch, "Your poofout is now %s", ch->pcdata->bamfout);
	}
	return;
}

CH_CMD (do_deny)
{
	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;

	one_argument (argument, arg);
	if (arg[0] == '\0')
	{
		chprintln (ch, "Deny whom?");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (IS_NPC (victim))
	{
		chprintln (ch, "Not on NPC's.");
		return;
	}

	if (get_trust (victim) >= get_trust (ch))
	{
		chprintln (ch, "You failed.");
		return;
	}

	SET_BIT (victim->act, PLR_DENY);
	chprintln (victim, "You are denied access!");
	sprintf (buf, "$N denies access to %s", victim->name);
	wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	chprintln (ch, "OK.");
	save_char_obj (victim);
	stop_fighting (victim, TRUE);
	do_function (victim, &do_quit, "");

	return;
}

CH_CMD (do_disconnect)
{
	char arg[MAX_INPUT_LENGTH];
	DESCRIPTOR_DATA *d;
	CHAR_DATA *victim;

	one_argument (argument, arg);
	if (arg[0] == '\0')
	{
		chprintln (ch, "Disconnect whom?");
		return;
	}

	if (is_number (arg))
	{
		int desc;

		desc = atoi (arg);
		for (d = descriptor_list; d != NULL; d = d->next)
		{
			if (d->descriptor == desc)
			{
				close_socket (d);
				chprintln (ch, "Ok.");
				return;
			}
		}
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

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

	for (d = descriptor_list; d != NULL; d = d->next)
	{
		if (d == victim->desc)
		{
			close_socket (d);
			chprintln (ch, "Ok.");
			return;
		}
	}

	bug ("Do_disconnect: desc not found.", 0);
	chprintln (ch, "Descriptor not found!");
	return;
}

CH_CMD (do_pardon)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;

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

	if (arg1[0] == '\0' || arg2[0] == '\0')
	{
		chprintln (ch, "Syntax: pardon <character> <killer|thief>.");
		return;
	}

	if ((victim = get_char_world (ch, arg1)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (IS_NPC (victim))
	{
		chprintln (ch, "Not on NPC's.");
		return;
	}

	if (!str_cmp (arg2, "killer"))
	{
		if (IS_SET (victim->act, PLR_KILLER))
		{
			REMOVE_BIT (victim->act, PLR_KILLER);
			chprintln (ch, "Killer flag removed.");
			chprintln (victim, "You are no longer a KILLER.");
		}
		return;
	}

	if (!str_cmp (arg2, "thief"))
	{
		if (IS_SET (victim->act, PLR_THIEF))
		{
			REMOVE_BIT (victim->act, PLR_THIEF);
			chprintln (ch, "Thief flag removed.");
			chprintln (victim, "You are no longer a THIEF.");
		}
		return;
	}

	chprintln (ch, "Syntax: pardon <character> <killer|thief>.");
	return;
}

CH_CMD (do_echo)
{
	DESCRIPTOR_DATA *d;

	if (argument[0] == '\0')
	{
		chprintln (ch, "Global echo what?");
		return;
	}

	for (d = descriptor_list; d; d = d->next)
	{
		if (d->connected == CON_PLAYING)
		{
			if (get_trust (d->character) >= get_trust (ch))
				chprint (d->character, "global> ");
			chprintln (d->character, argument);
		}
	}

	return;
}

CH_CMD (do_recho)
{
	DESCRIPTOR_DATA *d;

	if (argument[0] == '\0')
	{
		chprintln (ch, "Local echo what?");

		return;
	}

	for (d = descriptor_list; d; d = d->next)
	{
		if (d->connected == CON_PLAYING &&
			d->character->in_room == ch->in_room)
		{
			if (get_trust (d->character) >= get_trust (ch))
				chprint (d->character, "local> ");
			chprintln (d->character, argument);
		}
	}

	return;
}

CH_CMD (do_zecho)
{
	DESCRIPTOR_DATA *d;

	if (argument[0] == '\0')
	{
		chprintln (ch, "Zone echo what?");
		return;
	}

	for (d = descriptor_list; d; d = d->next)
	{
		if (d->connected == CON_PLAYING && d->character->in_room != NULL
			&& ch->in_room != NULL
			&& d->character->in_room->area == ch->in_room->area)
		{
			if (get_trust (d->character) >= get_trust (ch))
				chprint (d->character, "zone> ");
			chprintln (d->character, argument);
		}
	}
}

CH_CMD (do_pecho)
{
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;

	argument = one_argument (argument, arg);

	if (argument[0] == '\0' || arg[0] == '\0')
	{
		chprintln (ch, "Personal echo what?");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "Target not found.");
		return;
	}

	if (get_trust (victim) >= get_trust (ch) && get_trust (ch) != MAX_LEVEL)
		chprint (victim, "personal> ");

	chprintln (victim, argument);
	chprint (ch, "personal> ");
	chprintln (ch, argument);
}

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

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

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

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

	return NULL;
}

CH_CMD (do_transfer)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	ROOM_INDEX_DATA *location;
	DESCRIPTOR_DATA *d;
	CHAR_DATA *victim;

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

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

	if (!str_cmp (arg1, "all"))
	{
		for (d = descriptor_list; d != NULL; d = d->next)
		{
			if (d->connected == CON_PLAYING && d->character != ch &&
				d->character->in_room != NULL && can_see (ch, d->character))
			{
				char buf[MAX_STRING_LENGTH];
				sprintf (buf, "%s %s", d->character->name, arg2);
				do_function (ch, &do_transfer, 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)) == NULL)
		{
			chprintln (ch, "No such location.");
			return;
		}

		if (!is_room_owner (ch, location) && room_is_private (location)
			&& get_trust (ch) < MAX_LEVEL)
		{
			chprintln (ch, "That room is private right now.");
			return;
		}
	}

	if ((victim = get_char_world (ch, arg1)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (victim->in_room == NULL)
	{
		chprintln (ch, "They are in limbo.");
		return;
	}

	if (victim->fighting != NULL)
		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_function (victim, &do_look, "auto");
	chprintln (ch, "Ok.");
}

CH_CMD (do_at)
{
	char arg[MAX_INPUT_LENGTH];
	ROOM_INDEX_DATA *location;
	ROOM_INDEX_DATA *original;
	OBJ_DATA *on;
	CHAR_DATA *wch;

	argument = one_argument (argument, arg);

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

	if ((location = find_location (ch, arg)) == NULL)
	{
		chprintln (ch, "No such location.");
		return;
	}

	if (!is_room_owner (ch, location) && room_is_private (location) &&
		get_trust (ch) < MAX_LEVEL)
	{
		chprintln (ch, "That room is private right now.");
		return;
	}

	original = ch->in_room;
	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 != NULL; wch = wch->next)
	{
		if (wch == ch)
		{
			char_from_room (ch);
			char_to_room (ch, original);
			ch->on = on;
			break;
		}
	}

	return;
}

CH_CMD (do_goto)
{
	ROOM_INDEX_DATA *location;
	CHAR_DATA *rch;
	int count = 0;

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

	if ((location = find_location (ch, argument)) == NULL)
	{
		chprintln (ch, "No such location.");
		return;
	}

	count = 0;
	for (rch = location->people; rch != NULL; rch = rch->next_in_room)
		count++;

	if (!is_room_owner (ch, location) && room_is_private (location) &&
		(count > 1 || get_trust (ch) < MAX_LEVEL))
	{
		chprintln (ch, "That room is private right now.");
		return;
	}

	if (ch->fighting != NULL)
		stop_fighting (ch, TRUE);

	for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room)
	{
		if (get_trust (rch) >= ch->invis_level)
		{
			if (ch->pcdata != NULL && ch->pcdata->bamfout[0] != '\0')
				act ("$t", ch, ch->pcdata->bamfout, rch, TO_VICT);
			else
				act ("$n leaves in a swirling mist.", ch, NULL, rch, TO_VICT);
		}
	}

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

	for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room)
	{
		if (get_trust (rch) >= ch->invis_level)
		{
			if (ch->pcdata != NULL && ch->pcdata->bamfin[0] != '\0')
				act ("$t", ch, ch->pcdata->bamfin, rch, TO_VICT);
			else
				act ("$n appears in a swirling mist.", ch, NULL, rch,
					 TO_VICT);
		}
	}

	do_function (ch, &do_look, "auto");
	return;
}

CH_CMD (do_violate)
{
	ROOM_INDEX_DATA *location;
	CHAR_DATA *rch;

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

	if ((location = find_location (ch, argument)) == NULL)
	{
		chprintln (ch, "No such location.");
		return;
	}

	if (!room_is_private (location))
	{
		chprintln (ch, "That room isn't private, use goto.");
		return;
	}

	if (ch->fighting != NULL)
		stop_fighting (ch, TRUE);

	for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room)
	{
		if (get_trust (rch) >= ch->invis_level)
		{
			if (ch->pcdata != NULL && ch->pcdata->bamfout[0] != '\0')
				act ("$t", ch, ch->pcdata->bamfout, rch, TO_VICT);
			else
				act ("$n leaves in a swirling mist.", ch, NULL, rch, TO_VICT);
		}
	}

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

	for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room)
	{
		if (get_trust (rch) >= ch->invis_level)
		{
			if (ch->pcdata != NULL && ch->pcdata->bamfin[0] != '\0')
				act ("$t", ch, ch->pcdata->bamfin, rch, TO_VICT);
			else
				act ("$n appears in a swirling mist.", ch, NULL, rch,
					 TO_VICT);
		}
	}

	do_function (ch, &do_look, "auto");
	return;
}

/* RT to replace the 3 stat commands */

CH_CMD (do_stat)
{
	char arg[MAX_INPUT_LENGTH];
	const char *string;
	OBJ_DATA *obj;
	ROOM_INDEX_DATA *location;
	CHAR_DATA *victim;

	string = one_argument (argument, arg);
	if (arg[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  stat <name>");
		chprintln (ch, "  stat obj <name>");
		chprintln (ch, "  stat mob <name>");
		chprintln (ch, "  stat room <number>");
		return;
	}

	if (!str_cmp (arg, "room"))
	{
		do_function (ch, &do_rstat, string);
		return;
	}

	if (!str_cmp (arg, "obj"))
	{
		do_function (ch, &do_ostat, string);
		return;
	}

	if (!str_cmp (arg, "char") || !str_cmp (arg, "mob"))
	{
		do_function (ch, &do_mstat, string);
		return;
	}

	/* do it the old way */

	obj = get_obj_world (ch, argument);
	if (obj != NULL)
	{
		do_function (ch, &do_ostat, argument);
		return;
	}

	victim = get_char_world (ch, argument);
	if (victim != NULL)
	{
		do_function (ch, &do_mstat, argument);
		return;
	}

	location = find_location (ch, argument);
	if (location != NULL)
	{
		do_function (ch, &do_rstat, argument);
		return;
	}

	chprintln (ch, "Nothing by that name found anywhere.");
}

CH_CMD (do_rstat)
{
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_INPUT_LENGTH];
	ROOM_INDEX_DATA *location;
	OBJ_DATA *obj;
	CHAR_DATA *rch;
	int door;

	one_argument (argument, arg);
	location = (arg[0] == '\0') ? ch->in_room : find_location (ch, arg);
	if (location == NULL)
	{
		chprintln (ch, "No such location.");
		return;
	}

	if (!is_room_owner (ch, location) && ch->in_room != location &&
		room_is_private (location) && !IS_TRUSTED (ch, IMPLEMENTOR))
	{
		chprintln (ch, "That room is private right now.");
		return;
	}

	chprintlnf (ch, "Name: '%s'\n\rArea: '%s'", location->name,
				location->area->name);

	chprintlnf (ch,
				"Vnum: %ld  Sector: %d  Light: %d  Healing: %d  Mana: %d",
				location->vnum, location->sector_type, location->light,
				location->heal_rate, location->mana_rate);

	chprintf (ch, "Room flags: %s.\n\rDescription:\n\r%s",
			  flag_string (room_flags, location->room_flags),
			  location->description);

	if (location->extra_descr != NULL)
	{
		EXTRA_DESCR_DATA *ed;

		chprint (ch, "Extra description keywords: '");
		for (ed = location->extra_descr; ed; ed = ed->next)
		{
			chprint (ch, ed->keyword);
			if (ed->next != NULL)
				chprint (ch, " ");
		}
		chprintln (ch, "'.");
	}

	chprint (ch, "Characters:");
	for (rch = location->people; rch; rch = rch->next_in_room)
	{
		if (can_see (ch, rch))
		{
			chprint (ch, " ");
			one_argument (rch->name, buf);
			chprint (ch, buf);
		}
	}

	chprint (ch, ".\n\rObjects:   ");
	for (obj = location->contents; obj; obj = obj->next_content)
	{
		chprint (ch, " ");
		one_argument (obj->name, buf);
		chprint (ch, buf);
	}
	chprintln (ch, ".");

	for (door = 0; door <= 5; door++)
	{
		EXIT_DATA *pexit;

		if ((pexit = location->exit[door]) != NULL)
		{
			chprintf (ch,
					  "Door: %d.  To: %ld.  Key: %ld.  Exit flags: %s.\n\rKeyword: '%s'.  Description: %s",
					  door,
					  (pexit->u1.to_room ==
					   NULL ? -1 : pexit->u1.to_room->vnum),
					  pexit->key, flag_string (exit_flags, pexit->exit_info),
					  pexit->keyword,
					  pexit->description[0] !=
					  '\0' ? pexit->description : "(none).\n\r");
		}
	}

	return;
}

CH_CMD (do_ostat)
{
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_INPUT_LENGTH];
	AFFECT_DATA *paf;
	OBJ_DATA *obj;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Stat what?");
		return;
	}

	if ((obj = get_obj_world (ch, argument)) == NULL)
	{
		chprintln (ch, "Nothing like that in hell, earth, or heaven.");
		return;
	}

	chprintlnf (ch, "Name(s): %s", obj->name);

	chprintlnf (ch, "Vnum: %ld  Format: %s  Type: %s  Resets: %d",
				obj->pIndexData->vnum,
				obj->pIndexData->new_format ? "new" : "old",
				item_name (obj->item_type), obj->pIndexData->reset_num);

	chprintlnf (ch, "Short description: %s\n\rLong description: %s",
				obj->short_descr, obj->description);

	chprintlnf (ch, "Wear bits: %s\n\rExtra bits: %s",
				flag_string (wear_flags, obj->wear_flags),
				flag_string (extra_flags, obj->extra_flags));

	chprintlnf (ch, "Number: %d/%d  Weight: %d/%d/%d (10th pounds)", 1,
				get_obj_number (obj), obj->weight, get_obj_weight (obj),
				get_true_weight (obj));

	chprintlnf (ch, "Level: %d  Cost: %d  Condition: %d  Timer: %d",
				obj->level, obj->cost, obj->condition, obj->timer);

	chprintlnf (ch,
				"In room: %ld  In object: %s  Carried by: %s  Wear_loc: %d",
				obj->in_room == NULL ? 0 : obj->in_room->vnum,
				obj->in_obj == NULL ? "(none)" : obj->in_obj->short_descr,
				obj->carried_by == NULL ? "(none)" : can_see (ch,
															  obj->carried_by)
				? obj->carried_by->name : "someone", obj->wear_loc);

	chprintlnf (ch, "Values: %ld %ld %ld %ld %ld", obj->value[0],
				obj->value[1], obj->value[2], obj->value[3], obj->value[4]);

	/* now give out vital statistics as per identify */

	switch (obj->item_type)
	{
	case ITEM_SCROLL:
	case ITEM_POTION:
	case ITEM_PILL:
		chprintf (ch, "Level %ld spells of:", obj->value[0]);

		if (obj->value[1] >= 0 && obj->value[1] < maxSkill)
		{
			chprint (ch, " '");
			chprint (ch, skill_table[obj->value[1]].name);
			chprint (ch, "'");
		}

		if (obj->value[2] >= 0 && obj->value[2] < maxSkill)
		{
			chprint (ch, " '");
			chprint (ch, skill_table[obj->value[2]].name);
			chprint (ch, "'");
		}

		if (obj->value[3] >= 0 && obj->value[3] < maxSkill)
		{
			chprint (ch, " '");
			chprint (ch, skill_table[obj->value[3]].name);
			chprint (ch, "'");
		}

		if (obj->value[4] >= 0 && obj->value[4] < maxSkill)
		{
			chprint (ch, " '");
			chprint (ch, skill_table[obj->value[4]].name);
			chprint (ch, "'");
		}

		chprintln (ch, ".");
		break;

	case ITEM_WAND:
	case ITEM_STAFF:
		chprintf (ch, "Has %ld(%ld) charges of level %ld", obj->value[1],
				  obj->value[2], obj->value[0]);

		if (obj->value[3] >= 0 && obj->value[3] < maxSkill)
		{
			chprint (ch, " '");
			chprint (ch, skill_table[obj->value[3]].name);
			chprint (ch, "'");
		}

		chprintln (ch, ".");
		break;

	case ITEM_DRINK_CON:
		chprintlnf (ch, "It holds %s-colored %s.",
					liq_table[obj->value[2]].liq_color,
					liq_table[obj->value[2]].liq_name);
		break;

	case ITEM_WEAPON:
		chprint (ch, "Weapon type is ");
		switch (obj->value[0])
		{
		case (WEAPON_EXOTIC):
			chprintln (ch, "exotic");
			break;
		case (WEAPON_SWORD):
			chprintln (ch, "sword");
			break;
		case (WEAPON_DAGGER):
			chprintln (ch, "dagger");
			break;
		case (WEAPON_SPEAR):
			chprintln (ch, "spear/staff");
			break;
		case (WEAPON_MACE):
			chprintln (ch, "mace/club");
			break;
		case (WEAPON_AXE):
			chprintln (ch, "axe");
			break;
		case (WEAPON_FLAIL):
			chprintln (ch, "flail");
			break;
		case (WEAPON_WHIP):
			chprintln (ch, "whip");
			break;
		case (WEAPON_POLEARM):
			chprintln (ch, "polearm");
			break;
		default:
			chprintln (ch, "unknown");
			break;
		}
		if (obj->pIndexData->new_format)
			sprintf (buf, "Damage is %ldd%ld (average %ld)\n\r",
					 obj->value[1], obj->value[2],
					 (1 + obj->value[2]) * obj->value[1] / 2);
		else
			chprintlnf (ch, "Damage is %ld to %ld (average %ld)",
						obj->value[1], obj->value[2],
						(obj->value[1] + obj->value[2]) / 2);

		chprintlnf (ch, "Damage noun is %s.",
					(obj->value[3] > 0 &&
					 obj->value[3] <
					 MAX_DAMAGE_MESSAGE) ? attack_table[obj->value[3]].noun :
					"undefined");

		if (obj->value[4])		/* weapon flags */
		{
			chprintlnf (ch, "Weapons flags: %s",
						flag_string (weapon_type2, obj->value[4]));
		}
		break;

	case ITEM_ARMOR:
		chprintlnf (ch,
					"Armor class is %ld pierce, %ld bash, %ld slash, and %ld vs. magic",
					obj->value[0], obj->value[1], obj->value[2],
					obj->value[3]);
		break;

	case ITEM_CONTAINER:
		chprintlnf (ch,
					"Capacity: %ld#  Maximum weight: %ld#  flags: %s",
					obj->value[0], obj->value[3],
					flag_string (container_flags, obj->value[1]));
		if (obj->value[4] != 100)
		{
			chprintlnf (ch, "Weight multiplier: %ld%%", obj->value[4]);
		}
		break;
	}

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

		chprint (ch, "Extra description keywords: '");

		for (ed = obj->extra_descr; ed != NULL; ed = ed->next)
		{
			chprint (ch, ed->keyword);
			if (ed->next != NULL)
				chprint (ch, " ");
		}

		for (ed = obj->pIndexData->extra_descr; ed != NULL; ed = ed->next)
		{
			chprint (ch, ed->keyword);
			if (ed->next != NULL)
				chprint (ch, " ");
		}

		chprintln (ch, "'");
	}

	for (paf = obj->affected; paf != NULL; paf = paf->next)
	{
		chprintf (ch, "Affects %s by %d, level %d",
				  flag_string (apply_flags, paf->location), paf->modifier,
				  paf->level);
		if (paf->duration > -1)
			sprintf (buf, ", %d hours.", paf->duration);
		else
			sprintf (buf, ".");
		chprintln (ch, buf);
		if (paf->bitvector)
		{
			switch (paf->where)
			{
			case TO_AFFECTS:
				sprintf (buf, "Adds %s affect.",
						 flag_string (affect_flags, paf->bitvector));
				break;
			case TO_WEAPON:
				sprintf (buf, "Adds %s weapon flags.",
						 flag_string (weapon_type2, paf->bitvector));
				break;
			case TO_OBJECT:
				sprintf (buf, "Adds %s object flag.",
						 flag_string (extra_flags, paf->bitvector));
				break;
			case TO_IMMUNE:
				sprintf (buf, "Adds immunity to %s.",
						 flag_string (imm_flags, paf->bitvector));
				break;
			case TO_RESIST:
				sprintf (buf, "Adds resistance to %s.",
						 flag_string (imm_flags, paf->bitvector));
				break;
			case TO_VULN:
				sprintf (buf, "Adds vulnerability to %s.",
						 flag_string (imm_flags, paf->bitvector));
				break;
			default:
				sprintf (buf, "Unknown bit %d.", paf->where);
				break;
			}
			chprintln (ch, buf);
		}
	}

	if (!obj->enchanted)
		for (paf = obj->pIndexData->affected; paf != NULL; paf = paf->next)
		{
			chprintlnf (ch, "Affects %s by %d, level %d.",
						flag_string (apply_flags, paf->location),
						paf->modifier, paf->level);
			if (paf->bitvector)
			{
				switch (paf->where)
				{
				case TO_AFFECTS:
					sprintf (buf, "Adds %s affect.",
							 flag_string (affect_flags, paf->bitvector));
					break;
				case TO_OBJECT:
					sprintf (buf, "Adds %s object flag.",
							 flag_string (extra_flags, paf->bitvector));
					break;
				case TO_IMMUNE:
					sprintf (buf, "Adds immunity to %s.",
							 flag_string (imm_flags, paf->bitvector));
					break;
				case TO_RESIST:
					sprintf (buf, "Adds resistance to %s.",
							 flag_string (imm_flags, paf->bitvector));
					break;
				case TO_VULN:
					sprintf (buf, "Adds vulnerability to %s.",
							 flag_string (imm_flags, paf->bitvector));
					break;
				default:
					sprintf (buf, "Unknown bit %d.", paf->where);
					break;
				}
				chprintln (ch, buf);
			}
		}

	return;
}

CH_CMD (do_mstat)
{
	char arg[MAX_INPUT_LENGTH];
	AFFECT_DATA *paf;
	CHAR_DATA *victim;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Stat whom?");
		return;
	}

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

	chprintlnf (ch, "Name: %s", victim->name);

	chprintlnf (ch,
				"Vnum: %ld  Format: %s  Race: %s  Group: %d  Sex: %s  Room: %ld",
				IS_NPC (victim) ? victim->pIndexData->vnum : 0,
				IS_NPC (victim) ? victim->
				pIndexData->new_format ? "new" : "old" : "pc",
				race_table[victim->race].name,
				IS_NPC (victim) ? victim->group : 0,
				sex_table[victim->sex].name,
				victim->in_room == NULL ? 0 : victim->in_room->vnum);

	if (IS_NPC (victim))
	{
		chprintlnf (ch, "Count: %d  Killed: %d",
					victim->pIndexData->count, victim->pIndexData->killed);
	}

	chprintlnf (ch,
				"Str: %d(%d)  Int: %d(%d)  Wis: %d(%d)  Dex: %d(%d)  Con: %d(%d)",
				victim->perm_stat[STAT_STR], get_curr_stat (victim, STAT_STR),
				victim->perm_stat[STAT_INT], get_curr_stat (victim, STAT_INT),
				victim->perm_stat[STAT_WIS], get_curr_stat (victim, STAT_WIS),
				victim->perm_stat[STAT_DEX], get_curr_stat (victim, STAT_DEX),
				victim->perm_stat[STAT_CON], get_curr_stat (victim,
															STAT_CON));

	chprintlnf (ch,
				"Hp: %ld/%ld  Mana: %ld/%ld  Move: %ld/%ld  Practices: %d",
				victim->hit, victim->max_hit, victim->mana, victim->max_mana,
				victim->move, victim->max_move,
				IS_NPC (ch) ? 0 : victim->practice);

	chprintlnf (ch,
				"Lv: %d  Class: %s  Align: %d  Gold: %ld  Silver: %ld  Exp: %d",
				victim->level,
				IS_NPC (victim) ? "mobile" : class_short (victim),
				victim->alignment, victim->gold, victim->silver, victim->exp);

	chprintlnf (ch, "Armor: pierce: %d  bash: %d  slash: %d  magic: %d",
				GET_AC (victim, AC_PIERCE), GET_AC (victim, AC_BASH),
				GET_AC (victim, AC_SLASH), GET_AC (victim, AC_EXOTIC));

	chprintlnf (ch,
				"Hit: %d  Dam: %d  Saves: %d  Size: %s  Position: %s  Wimpy: %d",
				GET_HITROLL (victim), GET_DAMROLL (victim),
				victim->saving_throw, size_table[victim->size].name,
				position_table[victim->position].name, victim->wimpy);

	if (IS_NPC (victim) && victim->pIndexData->new_format)
	{
		chprintlnf (ch, "Damage: %dd%d  Message:  %s",
					victim->damage[DICE_NUMBER], victim->damage[DICE_TYPE],
					attack_table[victim->dam_type].noun);
	}
	chprintlnf (ch, "Fighting: %s",
				victim->fighting ? victim->fighting->name : "(none)");

	if (!IS_NPC (victim))
	{
		chprintlnf (ch, "Thirst: %d  Hunger: %d  Full: %d  Drunk: %d",
					victim->pcdata->condition[COND_THIRST],
					victim->pcdata->condition[COND_HUNGER],
					victim->pcdata->condition[COND_FULL],
					victim->pcdata->condition[COND_DRUNK]);
	}

	chprintlnf (ch, "Carry number: %d  Carry weight: %ld",
				victim->carry_number, get_carry_weight (victim) / 10);

	if (!IS_NPC (victim))
	{
		chprintlnf (ch,
					"Age: %d  Played: %d  Last Level: %d  Timer: %d",
					get_age (victim),
					(int) (victim->played + current_time -
						   victim->logon) / 3600, victim->pcdata->last_level,
					victim->timer);
	}

	if (IS_NPC (victim))
		chprintlnf (ch, "Act: %s", flag_string (act_flags, victim->act));
	else
		chprintlnf (ch, "Plr: %s", flag_string (plr_flags, victim->act));

	if (victim->comm)
	{
		chprintlnf (ch, "Comm: %s", flag_string (comm_flags, victim->comm));
	}

	if (IS_NPC (victim) && victim->off_flags)
	{
		chprintlnf (ch, "Offense: %s",
					flag_string (off_flags, victim->off_flags));
	}

	if (victim->imm_flags)
	{
		chprintlnf (ch, "Immune: %s",
					flag_string (imm_flags, victim->imm_flags));
	}

	if (victim->res_flags)
	{
		chprintlnf (ch, "Resist: %s",
					flag_string (imm_flags, victim->res_flags));
	}

	if (victim->vuln_flags)
	{
		chprintlnf (ch, "Vulnerable: %s",
					flag_string (imm_flags, victim->vuln_flags));
	}

	chprintlnf (ch, "Form: %s\n\rParts: %s",
				flag_string (form_flags, victim->form),
				flag_string (part_flags, victim->parts));

	if (victim->affected_by)
	{
		chprintlnf (ch, "Affected by %s",
					flag_string (affect_flags, victim->affected_by));
	}

	chprintlnf (ch, "Master: %s  Leader: %s  Pet: %s",
				victim->master ? victim->master->name : "(none)",
				victim->leader ? victim->leader->name : "(none)",
				victim->pet ? victim->pet->name : "(none)");

	if (!IS_NPC (victim))
	{
		chprintlnf (ch, "Security: %d.", victim->pcdata->security);	/* OLC */
	}

	chprintf (ch, "Short description: %s\n\rLong  description: %s",
			  victim->short_descr,
			  victim->long_descr[0] !=
			  '\0' ? victim->long_descr : "(none)\n\r");

	if (IS_NPC (victim) && victim->spec_fun != 0)
	{
		chprintlnf (ch, "Mobile has special procedure %s.",
					spec_name (victim->spec_fun));
	}
	if (victim->desc != NULL && victim->desc->desc_flags != 0)
	{
		chprintlnf (ch, "Descriptor Flags: %s",
					flag_string (desc_flags, victim->desc->desc_flags));
	}
	if (!IS_NPC (victim) && IS_SET (victim->act, PLR_QUESTOR))
	{
		OBJ_INDEX_DATA *questinfoobj;
		MOB_INDEX_DATA *questinfo;
		ROOM_INDEX_DATA *questroom =
			get_room_index (victim->pcdata->questloc);

		if (victim->pcdata->questmob == -1 || has_questobj (victim))
		{
			chprintlnf (ch, "%s's Quest is ALMOST complete.", victim->name);
		}
		else if (victim->pcdata->questobj > 0)
		{
			if (
				(questinfoobj =
				 get_obj_index (victim->pcdata->questobj)) != NULL)
			{
				chprintf (ch, "They are on a quest to recover %s. ",
						  questinfoobj->short_descr);
				if (questroom != NULL)
				{
					chprintlnf (ch, "(Room: %ld)", questroom->vnum);
				}
				else
					chprintln (ch, "");
			}
			else
				chprintln (ch, "BUG: player has NULL quest obj.");
		}
		else if (victim->pcdata->questmob > 0)
		{
			if ((questinfo = get_mob_index (victim->pcdata->questmob))
				!= NULL)
			{
				chprintf (ch, "They are on a quest to slay %s. ",
						  questinfo->short_descr);
				if (questroom != NULL)
				{
					chprintlnf (ch, "(Room: %ld)", questroom->vnum);
				}
				else
					chprintln (ch, "");
			}
			else
				chprintln (ch, "BUG: player has NULL quest mob.");
		}
	}

	for (paf = victim->affected; paf != NULL; paf = paf->next)
	{
		chprintlnf (ch,
					"Spell: '%s' modifies %s by %d for %d hours with bits %s, level %d.",
					skill_table[(int) paf->type].name,
					flag_string (apply_flags, paf->location), paf->modifier,
					paf->duration, flag_string (affect_flags,
												paf->bitvector), paf->level);
	}

	return;
}

/* ofind and mfind replaced with vnum, vnum skill also added */

CH_CMD (do_vnum)
{
	char arg[MAX_INPUT_LENGTH];
	const char *string;

	string = one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  vnum obj <name>");
		chprintln (ch, "  vnum mob <name>");
		chprintln (ch, "  vnum skill <skill or spell>");
		return;
	}

	if (!str_cmp (arg, "obj"))
	{
		do_function (ch, &do_ofind, string);
		return;
	}

	if (!str_cmp (arg, "mob") || !str_cmp (arg, "char"))
	{
		do_function (ch, &do_mfind, string);
		return;
	}

	if (!str_cmp (arg, "skill") || !str_cmp (arg, "spell"))
	{
		do_function (ch, &do_slookup, string);
		return;
	}
	/* do both */
	do_function (ch, &do_mfind, argument);
	do_function (ch, &do_ofind, argument);
}

CH_CMD (do_mfind)
{
	char arg[MAX_INPUT_LENGTH];
	MOB_INDEX_DATA *pMobIndex;
	vnum_t vnum;
	int nMatch;
	bool fAll;
	bool found;

	one_argument (argument, arg);
	if (arg[0] == '\0')
	{
		chprintln (ch, "Find whom?");
		return;
	}

	fAll = FALSE;				/* !str_cmp( arg, "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++)
	{
		if ((pMobIndex = get_mob_index (vnum)) != NULL)
		{
			nMatch++;
			if (fAll || is_name (argument, pMobIndex->player_name))
			{
				found = TRUE;
				chprintlnf (ch, "[%5ld] %s", pMobIndex->vnum,
							pMobIndex->short_descr);
			}
		}
	}

	if (!found)
		chprintln (ch, "No mobiles by that name.");

	return;
}

CH_CMD (do_ofind)
{
	char arg[MAX_INPUT_LENGTH];
	OBJ_INDEX_DATA *pObjIndex;
	vnum_t vnum;
	int nMatch;
	bool fAll;
	bool found;

	one_argument (argument, arg);
	if (arg[0] == '\0')
	{
		chprintln (ch, "Find what?");
		return;
	}

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

	/*
	 * Yeah, so iterating over all vnum's takes 10,000 loops.
	 * Get_obj_index is fast, and I don't feel like threading another link.
	 * Do you?
	 * -- Furey
	 */
	for (vnum = 0; nMatch < top_obj_index; vnum++)
	{
		if ((pObjIndex = get_obj_index (vnum)) != NULL)
		{
			nMatch++;
			if (fAll || is_name (argument, pObjIndex->name))
			{
				found = TRUE;
				chprintlnf (ch, "[%5ld] %s", pObjIndex->vnum,
							pObjIndex->short_descr);
			}
		}
	}

	if (!found)
		chprintln (ch, "No objects by that name.");

	return;
}

CH_CMD (do_owhere)
{
	char buf[MAX_INPUT_LENGTH];
	BUFFER *buffer;
	OBJ_DATA *obj;
	OBJ_DATA *in_obj;
	bool found;
	int number = 0, max_found;

	found = FALSE;
	number = 0;
	max_found = 200;

	buffer = new_buf ();

	if (argument[0] == '\0')
	{
		chprintln (ch, "Find what?");
		return;
	}

	for (obj = object_list; obj != NULL; obj = obj->next)
	{
		if (!can_see_obj (ch, obj) || !is_name (argument, obj->name) ||
			ch->level < obj->level)
			continue;

		found = TRUE;
		number++;

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

		if (in_obj->carried_by != NULL && can_see (ch, in_obj->carried_by)
			&& in_obj->carried_by->in_room != NULL)
			sprintf (buf, "%3d) %s is carried by %s [Room %ld]\n\r",
					 number, obj->short_descr, PERS (in_obj->carried_by,
													 ch),
					 in_obj->carried_by->in_room->vnum);
		else if (in_obj->in_room != NULL
				 && can_see_room (ch, in_obj->in_room))
			sprintf (buf, "%3d) %s is in %s [Room %ld]\n\r", number,
					 obj->short_descr, in_obj->in_room->name,
					 in_obj->in_room->vnum);
		else
			sprintf (buf, "%3d) %s is somewhere\n\r", number,
					 obj->short_descr);

		buf[0] = UPPER (buf[0]);
		add_buf (buffer, buf);

		if (number >= max_found)
			break;
	}

	if (!found)
		chprintln (ch, "Nothing like that in heaven or earth.");
	else
		page_to_char (buf_string (buffer), ch);

	free_buf (buffer);
}

CH_CMD (do_mwhere)
{
	char buf[MAX_STRING_LENGTH];
	BUFFER *buffer;
	CHAR_DATA *victim;
	bool found;
	int count = 0;

	if (argument[0] == '\0')
	{
		DESCRIPTOR_DATA *d;

		/* show characters logged */

		buffer = new_buf ();
		for (d = descriptor_list; d != NULL; d = d->next)
		{
			if (d->character != NULL && d->connected == CON_PLAYING &&
				d->character->in_room != NULL
				&& can_see (ch, d->character)
				&& can_see_room (ch, d->character->in_room))
			{
				victim = d->character;
				count++;
				if (d->original != NULL)
					sprintf (buf,
							 "%3d) %s (in the body of %s) is in %s [%ld]\n\r",
							 count, d->original->name,
							 victim->short_descr,
							 victim->in_room->name, victim->in_room->vnum);
				else
					sprintf (buf, "%3d) %s is in %s [%ld]\n\r",
							 count, victim->name,
							 victim->in_room->name, victim->in_room->vnum);
				add_buf (buffer, buf);
			}
		}

		page_to_char (buf_string (buffer), ch);
		free_buf (buffer);
		return;
	}

	found = FALSE;
	buffer = new_buf ();
	for (victim = char_list; victim != NULL; victim = victim->next)
	{
		if (victim->in_room != NULL && is_name (argument, victim->name))
		{
			found = TRUE;
			count++;
			sprintf (buf, "%3d) [%5ld] %-28s [%5ld] %s\n\r", count,
					 IS_NPC (victim) ? victim->pIndexData->vnum : 0,
					 IS_NPC (victim) ? victim->short_descr : victim->name,
					 victim->in_room->vnum, victim->in_room->name);
			add_buf (buffer, buf);
		}
	}

	if (!found)
		act ("You didn't find any $T.", ch, NULL, argument, TO_CHAR);
	else
		page_to_char (buf_string (buffer), ch);

	free_buf (buffer);

	return;
}

CH_CMD (do_reboo)
{
	chprintln (ch, "If you want to REBOOT, spell it out.");
	return;
}

CH_CMD (do_reboot)
{
	char buf[MAX_STRING_LENGTH];
	extern bool merc_down;
	DESCRIPTOR_DATA *d, *d_next;
	CHAR_DATA *vch;

	if (ch->invis_level < LEVEL_HERO)
	{
		sprintf (buf, "Reboot by %s.", ch->name);
		do_function (ch, &do_echo, buf);
	}
	if (war_info.iswar != WAR_OFF)
		end_war ();
	merc_down = TRUE;
	save_gquest_data ();
	for (d = descriptor_list; d != NULL; d = d_next)
	{
		d_next = d->next;
		vch = d->original ? d->original : d->character;
		if (vch != NULL)
			save_char_obj (vch);
		close_socket (d);
	}

	return;
}

CH_CMD (do_shutdow)
{
	chprintln (ch, "If you want to SHUTDOWN, spell it out.");
	return;
}

CH_CMD (do_shutdown)
{
	char buf[MAX_STRING_LENGTH];
	extern bool merc_down;
	DESCRIPTOR_DATA *d, *d_next;
	CHAR_DATA *vch;

	if (ch->invis_level < LEVEL_HERO)
		sprintf (buf, "Shutdown by %s.", ch->name);
	append_file (ch, SHUTDOWN_FILE, buf);
	strcat (buf, "\n\r");
	if (ch->invis_level < LEVEL_HERO)
	{
		do_function (ch, &do_echo, buf);
	}
	if (war_info.iswar != WAR_OFF)
		end_war ();
	merc_down = TRUE;
	save_gquest_data ();
	for (d = descriptor_list; d != NULL; d = d_next)
	{
		d_next = d->next;
		vch = d->original ? d->original : d->character;
		if (vch != NULL)
			save_char_obj (vch);
		close_socket (d);
	}
	return;
}

CH_CMD (do_protect)
{
	CHAR_DATA *victim;

	if (argument[0] == '\0')
	{
		chprintln (ch, "Protect whom from snooping?");
		return;
	}

	if ((victim = get_char_world (ch, argument)) == NULL)
	{
		chprintln (ch, "You can't find them.");
		return;
	}

	if (IS_SET (victim->comm, COMM_SNOOP_PROOF))
	{
		act_new ("$N is no longer snoop-proof.", ch, NULL, victim,
				 TO_CHAR, POS_DEAD);
		chprintln (victim, "Your snoop-proofing was just removed.");
		REMOVE_BIT (victim->comm, COMM_SNOOP_PROOF);
	}
	else
	{
		act_new ("$N is now snoop-proof.", ch, NULL, victim, TO_CHAR,
				 POS_DEAD);
		chprintln (victim, "You are now immune to snooping.");
		SET_BIT (victim->comm, COMM_SNOOP_PROOF);
	}
}

CH_CMD (do_snoop)
{
	char arg[MAX_INPUT_LENGTH];
	DESCRIPTOR_DATA *d;
	CHAR_DATA *victim;
	char buf[MAX_STRING_LENGTH];

	one_argument (argument, arg);

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

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (victim->desc == NULL)
	{
		chprintln (ch, "No descriptor to snoop.");
		return;
	}

	if (victim == ch)
	{
		chprintln (ch, "Cancelling all snoops.");
		wiznet ("$N stops being such a snoop.", ch, NULL, WIZ_SNOOPS,
				WIZ_SECURE, get_trust (ch));
		for (d = descriptor_list; d != NULL; d = d->next)
		{
			if (d->snoop_by == ch->desc)
				d->snoop_by = NULL;
		}
		return;
	}

	if (victim->desc->snoop_by != NULL)
	{
		chprintln (ch, "Busy already.");
		return;
	}

	if (!is_room_owner (ch, victim->in_room) &&
		ch->in_room != victim->in_room && room_is_private (victim->in_room)
		&& !IS_TRUSTED (ch, IMPLEMENTOR))
	{
		chprintln (ch, "That character is in a private room.");
		return;
	}

	if (get_trust (victim) >= get_trust (ch) ||
		IS_SET (victim->comm, COMM_SNOOP_PROOF))
	{
		chprintln (ch, "You failed.");
		return;
	}

	if (ch->desc != NULL)
	{
		for (d = ch->desc->snoop_by; d != NULL; d = d->snoop_by)
		{
			if (d->character == victim || d->original == victim)
			{
				chprintln (ch, "No snoop loops.");
				return;
			}
		}
	}

	victim->desc->snoop_by = ch->desc;
	sprintf (buf, "$N starts snooping on %s",
			 (IS_NPC (ch) ? victim->short_descr : victim->name));
	wiznet (buf, ch, NULL, WIZ_SNOOPS, WIZ_SECURE, get_trust (ch));
	chprintln (ch, "Ok.");
	return;
}

CH_CMD (do_switch)
{
	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Switch into whom?");
		return;
	}

	if (ch->desc == NULL)
		return;

	if (ch->desc->original != NULL)
	{
		chprintln (ch, "You are already switched.");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (victim == ch)
	{
		chprintln (ch, "Ok.");
		return;
	}

	if (!IS_NPC (victim))
	{
		chprintln (ch, "You can only switch into mobiles.");
		return;
	}

	if (!is_room_owner (ch, victim->in_room) &&
		ch->in_room != victim->in_room && room_is_private (victim->in_room)
		&& !IS_TRUSTED (ch, IMPLEMENTOR))
	{
		chprintln (ch, "That character is in a private room.");
		return;
	}

	if (victim->desc != NULL)
	{
		chprintln (ch, "Character in use.");
		return;
	}

	sprintf (buf, "$N switches into %s", victim->short_descr);
	wiznet (buf, ch, NULL, WIZ_SWITCHES, WIZ_SECURE, get_trust (ch));

	ch->desc->character = victim;
	ch->desc->original = ch;
	victim->desc = ch->desc;
	ch->desc = NULL;
	/* change communications to match */
	if (ch->prompt != NULL)
		victim->prompt = str_dup (ch->prompt);
	victim->comm = ch->comm;
	victim->lines = ch->lines;
	chprintln (victim, "Ok.");
	return;
}

CH_CMD (do_return)
{
	char buf[MAX_STRING_LENGTH];

	if (ch->desc == NULL)
		return;

	if (ch->desc->original == NULL)
	{
		chprintln (ch, "You aren't switched.");
		return;
	}

	chprintln (ch,
			   "You return to your original body. Type replay to see any missed tells.");
	if (ch->prompt != NULL)
	{
		free_string (ch->prompt);
		ch->prompt = NULL;
	}

	sprintf (buf, "$N returns from %s.", ch->short_descr);
	wiznet (buf, ch->desc->original, 0, WIZ_SWITCHES, WIZ_SECURE,
			get_trust (ch));
	ch->desc->character = ch->desc->original;
	ch->desc->original = NULL;
	ch->desc->character->desc = ch->desc;
	ch->desc = NULL;
	return;
}

/* trust levels for load and clone */
bool obj_check (CHAR_DATA * ch, OBJ_DATA * obj)
{
	if (IS_TRUSTED (ch, GOD) ||
		(IS_TRUSTED (ch, IMMORTAL) && obj->level <= 20 &&
		 obj->cost <= 1000) || (IS_TRUSTED (ch, DEMI) &&
								obj->level <= 10 && obj->cost <= 500) ||
		(IS_TRUSTED (ch, ANGEL) && obj->level <= 5 && obj->cost <= 250)
		|| (IS_TRUSTED (ch, AVATAR) && obj->level == 0 && obj->cost <= 100))
		return TRUE;
	else
		return FALSE;
}

/* for clone, to insure that cloning goes many levels deep */
void recursive_clone (CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * clone)
{
	OBJ_DATA *c_obj, *t_obj;

	for (c_obj = obj->contains; c_obj != NULL; c_obj = c_obj->next_content)
	{
		if (obj_check (ch, c_obj))
		{
			t_obj = create_object (c_obj->pIndexData, 0);
			clone_object (c_obj, t_obj);
			obj_to_obj (t_obj, clone);
			recursive_clone (ch, c_obj, t_obj);
		}
	}
}

/* command that is similar to load */
CH_CMD (do_clone)
{
	char arg[MAX_INPUT_LENGTH];
	const char *rest;
	CHAR_DATA *mob;
	OBJ_DATA *obj;

	rest = one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Clone what?");
		return;
	}

	if (!str_prefix (arg, "object"))
	{
		mob = NULL;
		obj = get_obj_here (ch, rest);
		if (obj == NULL)
		{
			chprintln (ch, "You don't see that here.");
			return;
		}
	}
	else if (!str_prefix (arg, "mobile") || !str_prefix (arg, "character"))
	{
		obj = NULL;
		mob = get_char_room (ch, rest);
		if (mob == NULL)
		{
			chprintln (ch, "You don't see that here.");
			return;
		}
	}
	else						/* find both */
	{
		mob = get_char_room (ch, argument);
		obj = get_obj_here (ch, argument);
		if (mob == NULL && obj == NULL)
		{
			chprintln (ch, "You don't see that here.");
			return;
		}
	}

	/* clone an object */
	if (obj != NULL)
	{
		OBJ_DATA *clone;

		if (!obj_check (ch, obj))
		{
			chprintln (ch,
					   "Your powers are not great enough for such a task.");
			return;
		}

		clone = create_object (obj->pIndexData, 0);
		clone_object (obj, clone);
		if (obj->carried_by != NULL)
			obj_to_char (clone, ch);
		else
			obj_to_room (clone, ch->in_room);
		recursive_clone (ch, obj, clone);

		act ("$n has created $p.", ch, clone, NULL, TO_ROOM);
		act ("You clone $p.", ch, clone, NULL, TO_CHAR);
		wiznet ("$N clones $p.", ch, clone, WIZ_LOAD, WIZ_SECURE,
				get_trust (ch));
		return;
	}
	else if (mob != NULL)
	{
		CHAR_DATA *clone;
		OBJ_DATA *new_pobj;
		char buf[MAX_STRING_LENGTH];

		if (!IS_NPC (mob))
		{
			chprintln (ch, "You can only clone mobiles.");
			return;
		}

		if ((mob->level > 20 && !IS_TRUSTED (ch, GOD)) ||
			(mob->level > 10 && !IS_TRUSTED (ch, IMMORTAL)) ||
			(mob->level > 5 && !IS_TRUSTED (ch, DEMI)) ||
			(mob->level > 0 && !IS_TRUSTED (ch, ANGEL)) ||
			!IS_TRUSTED (ch, AVATAR))
		{
			chprintln (ch,
					   "Your powers are not great enough for such a task.");
			return;
		}

		clone = create_mobile (mob->pIndexData);
		clone_mobile (mob, clone);

		for (obj = mob->carrying; obj != NULL; obj = obj->next_content)
		{
			if (obj_check (ch, obj))
			{
				new_pobj = create_object (obj->pIndexData, 0);
				clone_object (obj, new_pobj);
				recursive_clone (ch, obj, new_pobj);
				obj_to_char (new_pobj, clone);
				new_pobj->wear_loc = obj->wear_loc;
			}
		}
		char_to_room (clone, ch->in_room);
		act ("$n has created $N.", ch, NULL, clone, TO_ROOM);
		act ("You clone $N.", ch, NULL, clone, TO_CHAR);
		sprintf (buf, "$N clones %s.", clone->short_descr);
		wiznet (buf, ch, NULL, WIZ_LOAD, WIZ_SECURE, get_trust (ch));
		return;
	}
}

/* RT to replace the two load commands */

CH_CMD (do_load)
{
	char arg[MAX_INPUT_LENGTH];

	argument = one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  load mob <vnum>");
		chprintln (ch, "  load obj <vnum> <level>");
		return;
	}

	if (!str_cmp (arg, "mob") || !str_cmp (arg, "char"))
	{
		do_function (ch, &do_mload, argument);
		return;
	}

	if (!str_cmp (arg, "obj"))
	{
		do_function (ch, &do_oload, argument);
		return;
	}
	/* echo syntax */
	do_function (ch, &do_load, "");
}

CH_CMD (do_mload)
{
	char arg[MAX_INPUT_LENGTH];
	MOB_INDEX_DATA *pMobIndex;
	CHAR_DATA *victim;
	char buf[MAX_STRING_LENGTH];

	one_argument (argument, arg);

	if (arg[0] == '\0' || !is_number (arg))
	{
		chprintln (ch, "Syntax: load mob <vnum>.");
		return;
	}

	if ((pMobIndex = get_mob_index (atol (arg))) == NULL)
	{
		chprintln (ch, "No mob has that vnum.");
		return;
	}

	victim = create_mobile (pMobIndex);
	char_to_room (victim, ch->in_room);
	act ("$n has created $N!", ch, NULL, victim, TO_ROOM);
	sprintf (buf, "$N loads %s.", victim->short_descr);
	wiznet (buf, ch, NULL, WIZ_LOAD, WIZ_SECURE, get_trust (ch));
	chprintln (ch, "Ok.");
	return;
}

CH_CMD (do_oload)
{
	char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
	OBJ_INDEX_DATA *pObjIndex;
	OBJ_DATA *obj;
	int level;

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

	if (arg1[0] == '\0' || !is_number (arg1))
	{
		chprintln (ch, "Syntax: load obj <vnum> <level>.");
		return;
	}

	level = get_trust (ch);		/* default */

	if (arg2[0] != '\0')		/* load with a level */
	{
		if (!is_number (arg2))
		{
			chprintln (ch, "Syntax: oload <vnum> <level>.");
			return;
		}
		level = atoi (arg2);
		if (level < 0 || level > get_trust (ch))
		{
			chprintln (ch, "Level must be be between 0 and your level.");
			return;
		}
	}

	if ((pObjIndex = get_obj_index (atol (arg1))) == NULL)
	{
		chprintln (ch, "No object has that vnum.");
		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);
	act ("$n has created $p!", ch, obj, NULL, TO_ROOM);
	wiznet ("$N loads $p.", ch, obj, WIZ_LOAD, WIZ_SECURE, get_trust (ch));
	chprintln (ch, "Ok.");
	return;
}

CH_CMD (do_purge)
{
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	OBJ_DATA *obj;
	DESCRIPTOR_DATA *d;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		/* 'purge' */
		CHAR_DATA *vnext;
		OBJ_DATA *obj_next;

		for (victim = ch->in_room->people; victim != NULL; victim = vnext)
		{
			vnext = victim->next_in_room;
			if (IS_NPC (victim) && !IS_SET (victim->act, ACT_NOPURGE)
				&& victim != ch /* safety precaution */ )
				extract_char (victim, TRUE);
		}

		for (obj = ch->in_room->contents; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;
			if (!IS_OBJ_STAT (obj, ITEM_NOPURGE))
				extract_obj (obj);
		}

		act ("$n purges the room!", ch, NULL, NULL, TO_ROOM);
		chprintln (ch, "Ok.");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (!IS_NPC (victim))
	{

		if (ch == victim)
		{
			chprintln (ch, "Ho ho ho.");
			return;
		}

		if (get_trust (ch) <= get_trust (victim))
		{
			chprintln (ch, "Maybe that wasn't a good idea...");
			chprintlnf (victim, "%s tried to purge you!", ch->name);
			return;
		}

		act ("$n disintegrates $N.", ch, 0, victim, TO_NOTVICT);

		if (victim->level > 1)
			save_char_obj (victim);
		d = victim->desc;
		extract_char (victim, TRUE);
		if (d != NULL)
			close_socket (d);

		return;
	}

	act ("$n purges $N.", ch, NULL, victim, TO_NOTVICT);
	extract_char (victim, TRUE);
	return;
}

CH_CMD (do_advance)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	int level;
	int iLevel;

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

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

	if ((victim = get_char_world (ch, arg1)) == NULL)
	{
		chprintln (ch, "That player is not here.");
		return;
	}

	if (IS_NPC (victim))
	{
		chprintln (ch, "Not on NPC's.");
		return;
	}

	if ((level = atoi (arg2)) < 1 || level > MAX_LEVEL)
	{
		chprintlnf (ch, "Level must be 1 to %d.", MAX_LEVEL);
		return;
	}

	if (level > get_trust (ch))
	{
		chprintln (ch, "Limited to your trust level.");
		return;
	}

	/*
	 * Lower level:
	 *   Reset to level 1.
	 *   Then raise again.
	 *   Currently, an imp can lower another imp.
	 *   -- Swiftest
	 */
	if (level <= victim->level)
	{
		int temp_prac;

		chprintln (ch, "Lowering a player's level!");
		chprintln (victim, "**** OOOOHHHHHHHHHH  NNNNOOOO ****");
		temp_prac = victim->practice;
		victim->level = 1;
		victim->exp = exp_per_level (victim, victim->pcdata->points);
		victim->max_hit = 10;
		victim->max_mana = 100;
		victim->max_move = 100;
		victim->practice = 0;
		victim->hit = victim->max_hit;
		victim->mana = victim->max_mana;
		victim->move = victim->max_move;
		advance_level (victim, TRUE);
		victim->practice = temp_prac;
	}
	else
	{
		chprintln (ch, "Raising a player's level!");
		chprintln (victim, "**** OOOOHHHHHHHHHH  YYYYEEEESSS ****");
	}

	for (iLevel = victim->level; iLevel < level; iLevel++)
	{
		victim->level += 1;
		advance_level (victim, TRUE);
	}
	chprintlnf (victim, "You are now level %d.", victim->level);
	victim->exp =
		exp_per_level (victim, victim->pcdata->points) * UMAX (1,
															   victim->level);
	victim->trust = 0;
	save_char_obj (victim);
	return;
}

CH_CMD (do_trust)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	int level;

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

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

	if ((victim = get_char_world (ch, arg1)) == NULL)
	{
		chprintln (ch, "That player is not here.");
		return;
	}

	if ((level = atoi (arg2)) < 0 || level > MAX_LEVEL)
	{
		chprintlnf (ch, "Level must be 0 (reset) or 1 to %d.", MAX_LEVEL);
		return;
	}

	if (level > get_trust (ch))
	{
		chprintln (ch, "Limited to your trust.");
		return;
	}

	victim->trust = level;
	return;
}

CH_CMD (do_restore)
{
	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;
	CHAR_DATA *vch;
	DESCRIPTOR_DATA *d;

	one_argument (argument, arg);
	if (arg[0] == '\0' || !str_cmp (arg, "room"))
	{
		/* cure room */

		for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
		{
			affect_strip (vch, gsn_plague);
			affect_strip (vch, gsn_poison);
			affect_strip (vch, gsn_blindness);
			affect_strip (vch, gsn_sleep);
			affect_strip (vch, gsn_curse);

			vch->hit = vch->max_hit;
			vch->mana = vch->max_mana;
			vch->move = vch->max_move;
			update_pos (vch);
			act ("$n has restored you.", ch, NULL, vch, TO_VICT);
		}

		sprintf (buf, "$N restored room %ld.", ch->in_room->vnum);
		wiznet (buf, ch, NULL, WIZ_RESTORE, WIZ_SECURE, get_trust (ch));

		chprintln (ch, "Room restored.");
		return;

	}

	if (get_trust (ch) >= MAX_LEVEL - 1 && !str_cmp (arg, "all"))
	{
		/* cure all */

		for (d = descriptor_list; d != NULL; d = d->next)
		{
			victim = d->character;

			if (victim == NULL || IS_NPC (victim))
				continue;

			affect_strip (victim, gsn_plague);
			affect_strip (victim, gsn_poison);
			affect_strip (victim, gsn_blindness);
			affect_strip (victim, gsn_sleep);
			affect_strip (victim, gsn_curse);

			victim->hit = victim->max_hit;
			victim->mana = victim->max_mana;
			victim->move = victim->max_move;
			update_pos (victim);
			if (victim->in_room != NULL)
				act ("$n has restored you.", ch, NULL, victim, TO_VICT);
		}
		chprintln (ch, "All active players restored.");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	affect_strip (victim, gsn_plague);
	affect_strip (victim, gsn_poison);
	affect_strip (victim, gsn_blindness);
	affect_strip (victim, gsn_sleep);
	affect_strip (victim, gsn_curse);
	victim->hit = victim->max_hit;
	victim->mana = victim->max_mana;
	victim->move = victim->max_move;
	update_pos (victim);
	act ("$n has restored you.", ch, NULL, victim, TO_VICT);
	sprintf (buf, "$N restored %s",
			 IS_NPC (victim) ? victim->short_descr : victim->name);
	wiznet (buf, ch, NULL, WIZ_RESTORE, WIZ_SECURE, get_trust (ch));
	chprintln (ch, "Ok.");
	return;
}

CH_CMD (do_freeze)
{
	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Freeze whom?");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (IS_NPC (victim))
	{
		chprintln (ch, "Not on NPC's.");
		return;
	}

	if (get_trust (victim) >= get_trust (ch))
	{
		chprintln (ch, "You failed.");
		return;
	}

	if (IS_SET (victim->act, PLR_FREEZE))
	{
		REMOVE_BIT (victim->act, PLR_FREEZE);
		chprintln (victim, "You can play again.");
		chprintln (ch, "FREEZE removed.");
		sprintf (buf, "$N thaws %s.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}
	else
	{
		SET_BIT (victim->act, PLR_FREEZE);
		chprintln (victim, "You can't do ANYthing!");
		chprintln (ch, "FREEZE set.");
		sprintf (buf, "$N puts %s in the deep freeze.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}

	save_char_obj (victim);

	return;
}

CH_CMD (do_log)
{
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Log whom?");
		return;
	}

	if (!str_cmp (arg, "all"))
	{
		if (fLogAll)
		{
			fLogAll = FALSE;
			chprintln (ch, "Log ALL off.");
		}
		else
		{
			fLogAll = TRUE;
			chprintln (ch, "Log ALL on.");
		}
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (IS_NPC (victim))
	{
		chprintln (ch, "Not on NPC's.");
		return;
	}

	/*
	 * No level check, gods can log anyone.
	 */
	if (IS_SET (victim->act, PLR_LOG))
	{
		REMOVE_BIT (victim->act, PLR_LOG);
		chprintln (ch, "LOG removed.");
	}
	else
	{
		SET_BIT (victim->act, PLR_LOG);
		chprintln (ch, "LOG set.");
	}

	return;
}

CH_CMD (do_noemote)
{
	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Noemote whom?");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (get_trust (victim) >= get_trust (ch))
	{
		chprintln (ch, "You failed.");
		return;
	}

	if (IS_SET (victim->comm, COMM_NOEMOTE))
	{
		REMOVE_BIT (victim->comm, COMM_NOEMOTE);
		chprintln (victim, "You can emote again.");
		chprintln (ch, "NOEMOTE removed.");
		sprintf (buf, "$N restores emotes to %s.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}
	else
	{
		SET_BIT (victim->comm, COMM_NOEMOTE);
		chprintln (victim, "You can't emote!");
		chprintln (ch, "NOEMOTE set.");
		sprintf (buf, "$N revokes %s's emotes.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}

	return;
}

CH_CMD (do_noshout)
{
	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;

	one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Noshout whom?");
		return;
	}

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (IS_NPC (victim))
	{
		chprintln (ch, "Not on NPC's.");
		return;
	}

	if (get_trust (victim) >= get_trust (ch))
	{
		chprintln (ch, "You failed.");
		return;
	}

	if (IS_SET (victim->comm, COMM_NOSHOUT))
	{
		REMOVE_BIT (victim->comm, COMM_NOSHOUT);
		chprintln (victim, "You can shout again.");
		chprintln (ch, "NOSHOUT removed.");
		sprintf (buf, "$N restores shouts to %s.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}
	else
	{
		SET_BIT (victim->comm, COMM_NOSHOUT);
		chprintln (victim, "You can't shout!");
		chprintln (ch, "NOSHOUT set.");
		sprintf (buf, "$N revokes %s's shouts.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}

	return;
}

CH_CMD (do_notell)
{
	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;

	one_argument (argument, arg);

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

	if ((victim = get_char_world (ch, arg)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (get_trust (victim) >= get_trust (ch))
	{
		chprintln (ch, "You failed.");
		return;
	}

	if (IS_SET (victim->comm, COMM_NOTELL))
	{
		REMOVE_BIT (victim->comm, COMM_NOTELL);
		chprintln (victim, "You can tell again.");
		chprintln (ch, "NOTELL removed.");
		sprintf (buf, "$N restores tells to %s.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}
	else
	{
		SET_BIT (victim->comm, COMM_NOTELL);
		chprintln (victim, "You can't tell!");
		chprintln (ch, "NOTELL set.");
		sprintf (buf, "$N revokes %s's tells.", victim->name);
		wiznet (buf, ch, NULL, WIZ_PENALTIES, WIZ_SECURE, 0);
	}

	return;
}

CH_CMD (do_peace)
{
	CHAR_DATA *rch;

	for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room)
	{
		if (rch->fighting != NULL)
			stop_fighting (rch, TRUE);
		if (IS_NPC (rch) && IS_SET (rch->act, ACT_AGGRESSIVE))
			REMOVE_BIT (rch->act, ACT_AGGRESSIVE);
	}

	chprintln (ch, "Ok.");
	return;
}

CH_CMD (do_wizlock)
{
	extern bool wizlock;
	wizlock = !wizlock;

	if (wizlock)
	{
		wiznet ("$N has wizlocked the game.", ch, NULL, 0, 0, 0);
		chprintln (ch, "Game wizlocked.");
	}
	else
	{
		wiznet ("$N removes wizlock.", ch, NULL, 0, 0, 0);
		chprintln (ch, "Game un-wizlocked.");
	}

	return;
}

/* RT anti-newbie code */

CH_CMD (do_newlock)
{
	extern bool newlock;
	newlock = !newlock;

	if (newlock)
	{
		wiznet ("$N locks out new characters.", ch, NULL, 0, 0, 0);
		chprintln (ch, "New characters have been locked out.");
	}
	else
	{
		wiznet ("$N allows new characters back in.", ch, NULL, 0, 0, 0);
		chprintln (ch, "Newlock removed.");
	}

	return;
}

CH_CMD (do_slookup)
{
	char arg[MAX_INPUT_LENGTH];
	int sn;

	one_argument (argument, arg);
	if (arg[0] == '\0')
	{
		chprintln (ch, "Lookup which skill or spell?");
		return;
	}

	if (!str_cmp (arg, "all"))
	{
		for (sn = 0; sn < maxSkill; sn++)
		{
			if (skill_table[sn].name == NULL)
				break;
			chprintlnf (ch, "Sn: %3d  Skill/spell: '%s'",
						sn, skill_table[sn].name);
		}
	}
	else
	{
		if ((sn = skill_lookup (arg)) < 0)
		{
			chprintln (ch, "No such skill or spell.");
			return;
		}

		chprintlnf (ch, "Sn: %3d  Skill/spell: '%s'", sn,
					skill_table[sn].name);
	}

	return;
}

/* RT set replaces sset, mset, oset, and rset */

CH_CMD (do_set)
{
	char arg[MAX_INPUT_LENGTH];

	argument = one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  set mob   <name> <field> <value>");
		chprintln (ch, "  set obj   <name> <field> <value>");
		chprintln (ch, "  set room  <room> <field> <value>");
		chprintln (ch, "  set skill <name> <spell or skill> <value>");
		return;
	}

	if (!str_prefix (arg, "mobile") || !str_prefix (arg, "character"))
	{
		do_function (ch, &do_mset, argument);
		return;
	}

	if (!str_prefix (arg, "skill") || !str_prefix (arg, "spell"))
	{
		do_function (ch, &do_sset, argument);
		return;
	}

	if (!str_prefix (arg, "object"))
	{
		do_function (ch, &do_oset, argument);
		return;
	}

	if (!str_prefix (arg, "room"))
	{
		do_function (ch, &do_rset, argument);
		return;
	}
	/* echo syntax */
	do_function (ch, &do_set, "");
}

CH_CMD (do_sset)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char arg3[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	int value;
	int sn;
	bool fAll;

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

	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  set skill <name> <spell or skill> <value>");
		chprintln (ch, "  set skill <name> all <value>");
		chprintln (ch, "   (use the name of the skill, not the number)");
		return;
	}

	if ((victim = get_char_world (ch, arg1)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	if (IS_NPC (victim))
	{
		chprintln (ch, "Not on NPC's.");
		return;
	}

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

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

	value = atoi (arg3);
	if (value < 0 || value > 100)
	{
		chprintln (ch, "Value range is 0 to 100.");
		return;
	}

	if (fAll)
	{
		for (sn = 0; sn < maxSkill; sn++)
		{
			if (skill_table[sn].name != NULL)
				victim->pcdata->learned[sn] = value;
		}
	}
	else
	{
		victim->pcdata->learned[sn] = value;
	}

	return;
}

CH_CMD (do_mset)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char arg3[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	long value;

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

	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  set char <name> <field> <value>");
		chprintln (ch, "  Field being one of:");
		chprintln (ch, "    str int wis dex con sex class level");
		chprintln (ch, "    race group gold silver hp mana move prac");
		chprintln (ch, "    align train thirst hunger drunk full");
		chprintln (ch, "    security questpoints trivia");
		return;
	}

	if ((victim = get_char_world (ch, arg1)) == NULL)
	{
		chprintln (ch, "They aren't here.");
		return;
	}

	/* clear zones for mobs */
	victim->zone = NULL;

	/*
	 * Snarf the value (which need not be numeric).
	 */
	value = is_number (arg3) ? atol (arg3) : -1;

	/*
	 * Set something.
	 */
	if (!str_cmp (arg2, "str"))
	{
		if (value < 3 || value > get_max_train (victim, STAT_STR))
		{
			chprintlnf (ch, "Strength range is 3 to %d.",
						get_max_train (victim, STAT_STR));
			return;
		}

		victim->perm_stat[STAT_STR] = value;
		return;
	}

	if (!str_cmp (arg2, "security"))	/* OLC */
	{
		if (IS_NPC (ch))
		{
			chprintln (ch, "Si, claro.");
			return;
		}

		if (IS_NPC (victim))
		{
			chprintln (ch, "Not on NPC's.");
			return;
		}

		if (value > ch->pcdata->security || value < 0)
		{
			if (ch->pcdata->security != 0)
			{
				chprintlnf (ch, "Valid security is 0-%d.",
							ch->pcdata->security);
			}
			else
			{
				chprintln (ch, "Valid security is 0 only.");
			}
			return;
		}
		victim->pcdata->security = value;
		return;
	}

	if (!str_cmp (arg2, "int"))
	{
		if (value < 3 || value > get_max_train (victim, STAT_INT))
		{
			chprintlnf (ch, "Intelligence range is 3 to %d.",
						get_max_train (victim, STAT_INT));
			return;
		}

		victim->perm_stat[STAT_INT] = value;
		return;
	}

	if (!str_cmp (arg2, "wis"))
	{
		if (value < 3 || value > get_max_train (victim, STAT_WIS))
		{
			chprintlnf (ch, "Wisdom range is 3 to %d.",
						get_max_train (victim, STAT_WIS));
			return;
		}

		victim->perm_stat[STAT_WIS] = value;
		return;
	}

	if (!str_cmp (arg2, "dex"))
	{
		if (value < 3 || value > get_max_train (victim, STAT_DEX))
		{
			chprintlnf (ch, "Dexterity range is 3 to %d.",
						get_max_train (victim, STAT_DEX));
			return;
		}

		victim->perm_stat[STAT_DEX] = value;
		return;
	}

	if (!str_cmp (arg2, "con"))
	{
		if (value < 3 || value > get_max_train (victim, STAT_CON))
		{
			chprintlnf (ch, "Constitution range is 3 to %d.",
						get_max_train (victim, STAT_CON));
			return;
		}

		victim->perm_stat[STAT_CON] = value;
		return;
	}

	if (!str_prefix (arg2, "sex"))
	{
		if (value < 0 || value > 2)
		{
			chprintln (ch, "Sex range is 0 to 2.");
			return;
		}
		victim->sex = value;
		if (!IS_NPC (victim))
			victim->pcdata->true_sex = value;
		return;
	}

	if (!str_prefix (arg2, "class"))
	{
		char arg4[MAX_INPUT_LENGTH];
		char buf[MAX_STRING_LENGTH];
		int slot, value, iClass;

		argument = one_argument (argument, arg3);
		strcpy (arg4, argument);
		slot = (is_number (arg3)) ? atoi (arg3) : -1;
		value = (is_number (arg4)) ? atoi (arg4) : -1;
		if (value < -1)
			value = -1;
		if (slot < 1 || slot > MAX_REMORT)
		{
			chprintf (ch, "Invalid slot.  Valid slot: 1-%d.\n\r", MAX_REMORT);
			return;
		}

		for (iClass = 0; iClass < maxClass; iClass++)
		{
			if (!str_prefix (arg4, class_table[iClass].name)
				|| !str_cmp (arg4, class_table[iClass].who_name))
			{
				value = iClass;
				break;
			}
		}
		if (slot == 1 && value == -1)
		{
			chprintln (ch, "Cannot turn off 1st Class.");
			return;
		}
		if ((slot == 2 && value == -1 && victim->Class[2] != -1))
		{
			chprintln (ch, "You must turn off next to last class first.");
			return;
		}
		if (value < -1 || value >= maxClass)
		{
			chprintlnf (ch, "Class range is 0 to %d.", maxClass - 1);
			for (iClass = 0; iClass < maxClass; iClass++)
			{
				chprintlnf (ch, " %2d = %s", iClass,
							class_table[iClass].name);
			}
			chprintln (ch, " -1 = Turns off class.");
			return;
		}
		if (value != -1 && is_class (victim, value))
		{
			sprintf (buf, "$N is already %s %s.",
					 (victim->Class[1] != -1) ? "part" : "a",
					 class_table[value].name);
			act (buf, ch, NULL, victim, TO_CHAR);
			return;
		}
		victim->Class[slot - 1] = value;
		if (slot == MAX_REMORT)
			victim->Class[slot] = -1;
		chprintln (ch, "Ok.");
		return;
	}

	if (!str_prefix (arg2, "level"))
	{
		if (!IS_NPC (victim))
		{
			chprintln (ch, "Not on PC's.");
			return;
		}

		if (value < 0 || value > MAX_LEVEL)
		{
			chprintlnf (ch, "Level range is 0 to %d.", MAX_LEVEL);
			return;
		}
		victim->level = value;
		return;
	}

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

	if (!str_prefix (arg2, "silver"))
	{
		victim->silver = value;
		return;
	}
	if (!str_prefix (arg2, "questpoints"))
	{
		if (IS_NPC (victim))
		{
			chprintln (ch, "Not on NPC's.");
			return;
		}
		victim->pcdata->questpoints = value;
		return;
	}
	if (!str_prefix (arg2, "trivia"))
	{
		if (IS_NPC (victim))
		{
			chprintln (ch, "Not on NPC's.");
			return;
		}
		victim->pcdata->trivia = value;
		return;
	}

	if (!str_prefix (arg2, "hp"))
	{
		if (value < -10 || value > 30000)
		{
			chprintln (ch, "Hp range is -10 to 30,000 hit points.");
			return;
		}
		victim->max_hit = value;
		if (!IS_NPC (victim))
			victim->pcdata->perm_hit = value;
		return;
	}

	if (!str_prefix (arg2, "mana"))
	{
		if (value < 0 || value > 30000)
		{
			chprintln (ch, "Mana range is 0 to 30,000 mana points.");
			return;
		}
		victim->max_mana = value;
		if (!IS_NPC (victim))
			victim->pcdata->perm_mana = value;
		return;
	}

	if (!str_prefix (arg2, "move"))
	{
		if (value < 0 || value > 30000)
		{
			chprintln (ch, "Move range is 0 to 30,000 move points.");
			return;
		}
		victim->max_move = value;
		if (!IS_NPC (victim))
			victim->pcdata->perm_move = value;
		return;
	}

	if (!str_prefix (arg2, "practice"))
	{
		if (value < 0 || value > 250)
		{
			chprintln (ch, "Practice range is 0 to 250 sessions.");
			return;
		}
		victim->practice = value;
		return;
	}

	if (!str_prefix (arg2, "train"))
	{
		if (value < 0 || value > 50)
		{
			chprintln (ch, "Training session range is 0 to 50 sessions.");
			return;
		}
		victim->train = value;
		return;
	}

	if (!str_prefix (arg2, "align"))
	{
		if (value < -1000 || value > 1000)
		{
			chprintln (ch, "Alignment range is -1000 to 1000.");
			return;
		}
		victim->alignment = value;
		return;
	}

	if (!str_prefix (arg2, "thirst"))
	{
		if (IS_NPC (victim))
		{
			chprintln (ch, "Not on NPC's.");
			return;
		}

		if (value < -1 || value > 100)
		{
			chprintln (ch, "Thirst range is -1 to 100.");
			return;
		}

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

	if (!str_prefix (arg2, "drunk"))
	{
		if (IS_NPC (victim))
		{
			chprintln (ch, "Not on NPC's.");
			return;
		}

		if (value < -1 || value > 100)
		{
			chprintln (ch, "Drunk range is -1 to 100.");
			return;
		}

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

	if (!str_prefix (arg2, "full"))
	{
		if (IS_NPC (victim))
		{
			chprintln (ch, "Not on NPC's.");
			return;
		}

		if (value < -1 || value > 100)
		{
			chprintln (ch, "Full range is -1 to 100.");
			return;
		}

		victim->pcdata->condition[COND_FULL] = value;
		return;
	}

	if (!str_prefix (arg2, "hunger"))
	{
		if (IS_NPC (victim))
		{
			chprintln (ch, "Not on NPC's.");
			return;
		}

		if (value < -1 || value > 100)
		{
			chprintln (ch, "Full range is -1 to 100.");
			return;
		}

		victim->pcdata->condition[COND_HUNGER] = value;
		return;
	}

	if (!str_prefix (arg2, "race"))
	{
		int race;

		race = race_lookup (arg3);

		if (race == 0)
		{
			chprintln (ch, "That is not a valid race.");
			return;
		}

		if (!IS_NPC (victim) && !race_table[race].pc_race)
		{
			chprintln (ch, "That is not a valid player race.");
			return;
		}

		victim->race = race;
		return;
	}

	if (!str_prefix (arg2, "group"))
	{
		if (!IS_NPC (victim))
		{
			chprintln (ch, "Only on NPCs.");
			return;
		}
		victim->group = value;
		return;
	}

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

CH_CMD (do_string)
{
	char type[MAX_INPUT_LENGTH];
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char arg3[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	OBJ_DATA *obj;

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

	if (type[0] == '\0' || arg1[0] == '\0' || arg2[0] == '\0' ||
		arg3[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  string char <name> <field> <string>");
		chprintln (ch, "    fields: name short long desc title spec who");
		chprintln (ch, "  string obj  <name> <field> <string>");
		chprintln (ch, "    fields: name short long extended");
		return;
	}

	if (!str_prefix (type, "character") || !str_prefix (type, "mobile"))
	{
		if ((victim = get_char_world (ch, arg1)) == NULL)
		{
			chprintln (ch, "They aren't here.");
			return;
		}

		/* clear zone for mobs */
		victim->zone = NULL;

		/* string something */

		if (!str_prefix (arg2, "name"))
		{
			if (!IS_NPC (victim))
			{
				chprintln (ch, "Not on PC's.");
				return;
			}
			free_string (victim->name);
			victim->name = str_dup (arg3);
			return;
		}

		if (!str_prefix (arg2, "description"))
		{
			free_string (victim->description);
			victim->description = str_dup (arg3);
			return;
		}

		if (!str_prefix (arg2, "short"))
		{
			free_string (victim->short_descr);
			victim->short_descr = str_dup (arg3);
			return;
		}

		if (!str_prefix (arg2, "long"))
		{
			free_string (victim->long_descr);
			strcat (arg3, "\n\r");
			victim->long_descr = str_dup (arg3);
			return;
		}

		if (!str_prefix (arg2, "title"))
		{
			if (IS_NPC (victim))
			{
				chprintln (ch, "Not on NPC's.");
				return;
			}

			set_title (victim, arg3);
			return;
		}

		if (!str_prefix (arg2, "who"))
		{
			if (IS_NPC (victim))
			{
				chprintln (ch, "Not on NPC's.");
				return;
			}
			if (!str_cmp (arg3, "none"))
			{
				free_string (victim->pcdata->who_descr);
				victim->pcdata->who_descr = str_dup ("");
				return;
			}
			if (strlen_color (arg3) > 14)
			{
				chprintln (ch, "Limited to 14 characters. (minus color)");
				return;
			}
			free_string (victim->pcdata->who_descr);
			victim->pcdata->who_descr = str_dup (arg3);
			return;
		}
		if (!str_prefix (arg2, "spec"))
		{
			if (!IS_NPC (victim))
			{
				chprintln (ch, "Not on PC's.");
				return;
			}

			if ((victim->spec_fun = spec_lookup (arg3)) == 0)
			{
				chprintln (ch, "No such spec fun.");
				return;
			}

			return;
		}
	}

	if (!str_prefix (type, "object"))
	{
		/* string an obj */

		if ((obj = get_obj_world (ch, arg1)) == NULL)
		{
			chprintln (ch, "Nothing like that in heaven or earth.");
			return;
		}

		if (!str_prefix (arg2, "name"))
		{
			free_string (obj->name);
			obj->name = str_dup (arg3);
			return;
		}

		if (!str_prefix (arg2, "short"))
		{
			free_string (obj->short_descr);
			obj->short_descr = str_dup (arg3);
			return;
		}

		if (!str_prefix (arg2, "long"))
		{
			free_string (obj->description);
			obj->description = str_dup (arg3);
			return;
		}

		if (!str_prefix (arg2, "ed") || !str_prefix (arg2, "extended"))
		{
			EXTRA_DESCR_DATA *ed;
			char buf[MAX_STRING_LENGTH];

			argument = one_argument (argument, arg3);
			if (argument == NULL)
			{
				chprintln (ch, "Syntax: oset <object> ed <keyword> <string>");
				return;
			}

			strcpy (buf, argument);
			strcat (buf, "\n\r");

			ed = new_extra_descr ();

			ed->keyword = str_dup (arg3);
			ed->description = str_dup (buf);
			ed->next = obj->extra_descr;
			obj->extra_descr = ed;
			return;
		}
	}

	/* echo bad use message */
	do_function (ch, &do_string, "");
}

CH_CMD (do_oset)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char arg3[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;
	long value;

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

	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  set obj <object> <field> <value>");
		chprintln (ch, "  Field being one of:");
		chprintln (ch, "    value0 value1 value2 value3 value4 (v1-v4)");
		chprintln (ch, "    extra wear level weight cost timer");
		return;
	}

	if ((obj = get_obj_world (ch, arg1)) == NULL)
	{
		chprintln (ch, "Nothing like that in heaven or earth.");
		return;
	}

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

	/*
	 * Set something.
	 */
	if (!str_cmp (arg2, "value0") || !str_cmp (arg2, "v0"))
	{
		obj->value[0] = UMIN (50, 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, "value4") || !str_cmp (arg2, "v4"))
	{
		obj->value[4] = value;
		return;
	}

	if (!str_prefix (arg2, "extra"))
	{
		obj->extra_flags = value;
		return;
	}

	if (!str_prefix (arg2, "wear"))
	{
		obj->wear_flags = value;
		return;
	}

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

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

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

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

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

CH_CMD (do_rset)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char arg3[MAX_INPUT_LENGTH];
	ROOM_INDEX_DATA *location;
	long value;

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

	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
	{
		chprintln (ch, "Syntax:");
		chprintln (ch, "  set room <location> <field> <value>");
		chprintln (ch, "  Field being one of:");
		chprintln (ch, "    flags sector");
		return;
	}

	if ((location = find_location (ch, arg1)) == NULL)
	{
		chprintln (ch, "No such location.");
		return;
	}

	if (!is_room_owner (ch, location) && ch->in_room != location &&
		room_is_private (location) && !IS_TRUSTED (ch, IMPLEMENTOR))
	{
		chprintln (ch, "That room is private right now.");
		return;
	}

	/*
	 * Snarf the value.
	 */
	if (!is_number (arg3))
	{
		chprintln (ch, "Value must be numeric.");
		return;
	}
	value = atol (arg3);

	/*
	 * Set something.
	 */
	if (!str_prefix (arg2, "flags"))
	{
		location->room_flags = value;
		return;
	}

	if (!str_prefix (arg2, "sector"))
	{
		location->sector_type = value;
		return;
	}

	/*
	 * Generate usage message.
	 */
	do_function (ch, &do_rset, "");
	return;
}

CH_CMD (do_sockets)
{
	char buf[2 * MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	char arg[MAX_INPUT_LENGTH];
	DESCRIPTOR_DATA *d;
	int count;

	count = 0;
	buf[0] = '\0';

	one_argument (argument, arg);
	for (d = descriptor_list; d != NULL; d = d->next)
	{
		if (d->character != NULL && can_see (ch, d->character) &&
			(arg[0] == '\0' || is_name (arg, d->character->name) ||
			 (d->original && is_name (arg, d->original->name))))
		{
			count++;
			sprintf (buf + strlen (buf), "[%3d %2d] %s@%s\n\r",
					 d->descriptor, d->connected,
					 d->original ? d->original->name : d->
					 character ? d->character->name : "(none)", d->host);
		}
	}
	if (count == 0)
	{
		chprintln (ch, "No one by that name is connected.");
		return;
	}

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

/*
 * Thanks to Grodyn for pointing out bugs in this function.
 */
CH_CMD (do_force)
{
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];

	argument = one_argument (argument, arg);

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

	one_argument (argument, arg2);

	if (!str_cmp (arg2, "delete") || !str_prefix (arg2, "mob"))
	{
		chprintln (ch, "That will NOT be done.");
		return;
	}

	sprintf (buf, "$n forces you to '%s'.", argument);

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

		if (get_trust (ch) < MAX_LEVEL - 3)
		{
			chprintln (ch, "Not at your level!");
			return;
		}

		for (vch = char_list; vch != NULL; vch = vch_next)
		{
			vch_next = vch->next;

			if (!IS_NPC (vch) && get_trust (vch) < get_trust (ch))
			{
				act (buf, ch, NULL, vch, TO_VICT);
				interpret (vch, argument);
			}
		}
	}
	else if (!str_cmp (arg, "players"))
	{
		CHAR_DATA *vch;
		CHAR_DATA *vch_next;

		if (get_trust (ch) < MAX_LEVEL - 2)
		{
			chprintln (ch, "Not at your level!");
			return;
		}

		for (vch = char_list; vch != NULL; vch = vch_next)
		{
			vch_next = vch->next;

			if (!IS_NPC (vch) && get_trust (vch) < get_trust (ch) &&
				vch->level < LEVEL_HERO)
			{
				act (buf, ch, NULL, vch, TO_VICT);
				interpret (vch, argument);
			}
		}
	}
	else if (!str_cmp (arg, "gods"))
	{
		CHAR_DATA *vch;
		CHAR_DATA *vch_next;

		if (get_trust (ch) < MAX_LEVEL - 2)
		{
			chprintln (ch, "Not at your level!");
			return;
		}

		for (vch = char_list; vch != NULL; vch = vch_next)
		{
			vch_next = vch->next;

			if (!IS_NPC (vch) && get_trust (vch) < get_trust (ch) &&
				vch->level >= LEVEL_HERO)
			{
				act (buf, ch, NULL, vch, TO_VICT);
				interpret (vch, argument);
			}
		}
	}
	else
	{
		CHAR_DATA *victim;

		if ((victim = get_char_world (ch, arg)) == NULL)
		{
			chprintln (ch, "They aren't here.");
			return;
		}

		if (victim == ch)
		{
			chprintln (ch, "Aye aye, right away!");
			return;
		}

		if (!is_room_owner (ch, victim->in_room) &&
			ch->in_room != victim->in_room &&
			room_is_private (victim->in_room) &&
			!IS_TRUSTED (ch, IMPLEMENTOR))
		{
			chprintln (ch, "That character is in a private room.");
			return;
		}

		if (get_trust (victim) >= get_trust (ch))
		{
			chprintln (ch, "Do it yourself!");
			return;
		}

		if (!IS_NPC (victim) && get_trust (ch) < MAX_LEVEL - 3)
		{
			chprintln (ch, "Not at your level!");
			return;
		}

		act (buf, ch, NULL, victim, TO_VICT);
		interpret (victim, argument);
	}

	chprintln (ch, "Ok.");
	return;
}

/*
 * New routines by Dionysos.
 */
CH_CMD (do_invis)
{
	int level;
	char arg[MAX_STRING_LENGTH];

	/* RT code for taking a level argument */
	one_argument (argument, arg);

	if (arg[0] == '\0')
		/* take the default path */

		if (ch->invis_level)
		{
			ch->invis_level = 0;
			act ("$n slowly fades into existence.", ch, NULL, NULL, TO_ROOM);
			chprintln (ch, "You slowly fade back into existence.");
		}
		else
		{
			ch->invis_level = get_trust (ch);
			act ("$n slowly fades into thin air.", ch, NULL, NULL, TO_ROOM);
			chprintln (ch, "You slowly vanish into thin air.");
		}
	else
		/* do the level thing */
	{
		level = atoi (arg);
		if (level < 2 || level > get_trust (ch))
		{
			chprintln (ch, "Invis level must be between 2 and your level.");
			return;
		}
		else
		{
			ch->reply = NULL;
			ch->invis_level = level;
			act ("$n slowly fades into thin air.", ch, NULL, NULL, TO_ROOM);
			chprintln (ch, "You slowly vanish into thin air.");
		}
	}

	return;
}

CH_CMD (do_incognito)
{
	int level;
	char arg[MAX_STRING_LENGTH];

	/* RT code for taking a level argument */
	one_argument (argument, arg);

	if (arg[0] == '\0')
		/* take the default path */

		if (ch->incog_level)
		{
			ch->incog_level = 0;
			act ("$n is no longer cloaked.", ch, NULL, NULL, TO_ROOM);
			chprintln (ch, "You are no longer cloaked.");
		}
		else
		{
			ch->incog_level = get_trust (ch);
			act ("$n cloaks $s presence.", ch, NULL, NULL, TO_ROOM);
			chprintln (ch, "You cloak your presence.");
		}
	else
		/* do the level thing */
	{
		level = atoi (arg);
		if (level < 2 || level > get_trust (ch))
		{
			chprintln (ch, "Incog level must be between 2 and your level.");
			return;
		}
		else
		{
			ch->reply = NULL;
			ch->incog_level = level;
			act ("$n cloaks $s presence.", ch, NULL, NULL, TO_ROOM);
			chprintln (ch, "You cloak your presence.");
		}
	}

	return;
}

CH_CMD (do_holylight)
{
	if (IS_NPC (ch))
		return;

	if (IS_SET (ch->act, PLR_HOLYLIGHT))
	{
		REMOVE_BIT (ch->act, PLR_HOLYLIGHT);
		chprintln (ch, "Holy light mode off.");
	}
	else
	{
		SET_BIT (ch->act, PLR_HOLYLIGHT);
		chprintln (ch, "Holy light mode on.");
	}

	return;
}

/* prefix command: it will put the string typed on each line typed */

CH_CMD (do_prefi)
{
	chprintln (ch, "You cannot abbreviate the prefix command.");
	return;
}

CH_CMD (do_prefix)
{
	char buf[MAX_INPUT_LENGTH];

	if (argument[0] == '\0')
	{
		if (ch->prefix[0] == '\0')
		{
			chprintln (ch, "You have no prefix to clear.");
			return;
		}

		chprintln (ch, "Prefix removed.");
		free_string (ch->prefix);
		ch->prefix = str_dup ("");
		return;
	}

	if (ch->prefix[0] != '\0')
	{
		sprintf (buf, "Prefix changed to %s.\r\n", argument);
		free_string (ch->prefix);
	}
	else
	{
		sprintf (buf, "Prefix set to %s.\r\n", argument);
	}

	ch->prefix = str_dup (argument);
}

/* This file holds the copyover data */
#define COPYOVER_FILE "copyover.data"

/* This is the executable file */
#define EXE_FILE	  "../src/rom"

bool write_to_descriptor args ((DESCRIPTOR_DATA * d, char *txt, int length));

/*  Copyover - Original idea: Fusion of MUD++
 *  Adapted to Diku by Erwin S. Andreasen, <erwin@andreasen.org>
 *  http://www.andreasen.org
 *  Changed into a ROM patch after seeing the 100th request for it :)
 */
CH_CMD (do_copyover)
{
	FILE *fp;
	DESCRIPTOR_DATA *d, *d_next;
	char buf[100], buf2[100];
	extern int port, control;	/* db.c */

	fp = file_open (COPYOVER_FILE, "w");

	if (!fp)
	{
		if (ch)
			chprintln (ch, "Copyover file not writeable, aborted.");
		logf ("Could not write to copyover file: %s", COPYOVER_FILE);
		perror ("do_copyover:file_open");
		return;
	}

	/* Consider changing all saved areas here, if you use OLC */

	do_asave (NULL, "");

	save_gquest_data ();

	if (war_info.iswar != WAR_OFF)
		end_war ();

	sprintf (buf, "\n\r *** COPYOVER by %s - please remain seated!\n\r",
			 ch ? ch->name : "System");

	/* For each playing descriptor, save its state */
	for (d = descriptor_list; d; d = d_next)
	{
		CHAR_DATA *och = CH (d);
		d_next = d->next;		/* We delete from the list , so need to save this */

#if !defined(NO_MCCP)
		compressEnd (d);
#endif

		if (!d->character || d->connected > CON_PLAYING)	/* drop those logging on */
		{
			write_to_descriptor (d,
								 "\n\rSorry, we are rebooting. Come back in a few minutes.\n\r",
								 0);
			close_socket (d);	/* throw'em out */
		}
		else
		{
			long dflags = d->desc_flags;

			fprintf (fp, "%d %s %s %ld\n", d->descriptor, och->name,
					 d->host, dflags);

#if 0							/* This is not necessary for ROM */
			if (och->level == 1)
			{
				write_to_descriptor (d,
									 "Since you are level one, and level one characters do not save, you gain a free level!\n\r",
									 0);
				advance_level (och);
				och->level++;	/* Advance_level doesn't do that */
			}
#endif
			save_char_obj (och);

			write_to_descriptor (d, buf, 0);
		}
	}

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

	/* Close reserve and other always-open files and release other resources */

	fclose (fpReserve);

	/* exec - descriptors are inherited */

	sprintf (buf, "%d", port);
	sprintf (buf2, "%d", control);
	execl (EXE_FILE, "rom", buf, "copyover", buf2, (char *) NULL);

	/* Failed - sucessful exec will not return */

	perror ("do_copyover: execl");
	chprintln (ch, "Copyover FAILED!");

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

/* Recover from a copyover - load players */
void copyover_recover ()
{
	DESCRIPTOR_DATA *d;
	FILE *fp;
	char name[100];
	char host[MSL];
	int desc;
	long dflags;
	bool fOld;

	logf ("Copyover recovery initiated");

	fp = file_open (COPYOVER_FILE, "r");

	if (!fp)					/* there are some descriptors open which will hang forever then ? */
	{
		perror ("copyover_recover:file_open");
		logf ("Copyover file not found. Exitting.\n\r");
		exit (1);
	}

	unlink (COPYOVER_FILE);		/* In case something crashes - doesn't prevent reading  */

	for (;;)
	{
		fscanf (fp, "%d %s %s %ld\n", &desc, name, host, &dflags);
		if (desc == -1)
			break;

		d = new_descriptor ();
		d->descriptor = desc;
		d->desc_flags = dflags;
		d->host = str_dup (host);
		d->next = descriptor_list;
		descriptor_list = d;
		d->connected = CON_COPYOVER_RECOVER;	/* -15, so close_socket frees the char */

		init_telnet (d);

		/* Write something, and check if it goes error-free */
		if (!write_to_descriptor (d, "\n\rRestoring from copyover...\n\r", 0))
		{
			close (desc);		/* nope */
			continue;
		}

		/* Now, find the pfile */

		fOld = load_char_obj (d, name);

		if (!fOld)				/* Player file not found?! */
		{
			write_to_descriptor (d,
								 "\n\rSomehow, your character was lost in the copyover. Sorry.\n\r",
								 0);
			close_socket (d);
		}
		else					/* ok! */
		{
			write_to_descriptor (d, "\n\rCopyover recovery complete.\n\r", 0);

			/* Just In Case */
			if (!d->character->in_room)
				d->character->in_room = get_room_index (ROOM_VNUM_TEMPLE);

			/* Insert in the char_list */
			d->character->next = char_list;
			char_list = d->character;

			d->character->next_player = player_list;
			player_list = d->character;

			char_to_room (d->character, d->character->in_room);
			do_look (d->character, "auto");
			checkcorpse (d->character);
			act ("$n materializes!", d->character, NULL, NULL, TO_ROOM);
			d->connected = CON_PLAYING;

			if (d->character->pet != NULL)
			{
				char_to_room (d->character->pet, d->character->in_room);
				act ("$n materializes!.", d->character->pet, NULL,
					 NULL, TO_ROOM);
			}
		}

	}
	file_close (fp);

}