1stMUD/corefiles/
1stMUD/gods/
1stMUD/notes/
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
#include "webserver.h"
#include "magic.h"

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

CH_CMD(do_wiznet)
{
	int 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 == 0 || 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_first; 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;
	CLAN_DATA *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 = NULL;
		victim->rank = 0;
		update_members(victim, TRUE);
		return;
	}

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

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

	if (is_clan(victim))
	{
		update_members(victim, TRUE);
	}

	victim->clan = clan;
	victim->rank = 0;
	update_members(victim, FALSE);
}

/* 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);
	}

	act("You have been equipped by $g.", ch, NULL, NULL, TO_CHAR);
}

/* 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->first_person; 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_first; 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_first; 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_first; 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_first; 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_first; 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_first; 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_first; 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->first_person; 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->first_person; 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->first_person; 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->first_person; 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->first_person; 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->first_extra_descr != NULL)
	{
		EXTRA_DESCR_DATA *ed;

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

	chprint(ch, "Characters:");
	for (rch = location->first_person; 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->first_content; 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->first_extra_descr != NULL
		|| obj->pIndexData->first_extra_descr != NULL)
	{
		EXTRA_DESCR_DATA *ed;

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

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

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

		chprintln(ch, "'");
	}

	for (paf = obj->first_affect; 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->first_affect; 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",
			   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->d_flags != 0)
	{
		chprintlnf(ch, "Descriptor Flags: %s",
				   flag_string(desc_flags, victim->desc->d_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->first_affect; 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_first; 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_first; 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_first; 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();
	while (auction_first != NULL)
		reset_auc(auction_first, TRUE);
	save_donation_pit();
	merc_down = TRUE;
	save_gquest_data();
	for (d = descriptor_first; 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();
	while (auction_first != NULL)
		reset_auc(auction_first, TRUE);
	save_donation_pit();
	merc_down = TRUE;
	save_gquest_data();
	for (d = descriptor_first; 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_first; 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->first_content; 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, NULL, 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, NULL, rest);
		if (mob == NULL)
		{
			chprintln(ch, "You don't see that here.");
			return;
		}
	}
	else						/* find both */
	{
		mob = get_char_room(ch, NULL, argument);
		obj = get_obj_here(ch, NULL, 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->first_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->first_person; 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->first_content; 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->first_person; 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_first; 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->first_person; 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 clan rank");
		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, "clan"))
	{
		CLAN_DATA *clan;

		clan = clan_lookup(arg3);

		if (clan == NULL)
		{
			chprintln(ch, "Thats not a valid clan.");
			return;
		}

		victim->clan = clan;
		chprintln(ch, "Ok.");
		return;
	}

	if (!str_prefix(arg2, "rank"))
	{
		if (value < 0 || value >= MAX_RANK)
		{
			chprintlnf(ch, "Rank must be between %d and %d.", 0, MAX_RANK);
			return;
		}

		victim->rank = value;
		chprintln(ch, "Ok.");
		return;
	}
	if (!str_prefix(arg2, "race"))
	{
		RACE_DATA *race;

		race = race_lookup(arg3);

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

		if (!IS_NPC(victim) && !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);
			LINK(ed, obj->first_extra_descr, obj->last_extra_descr, next, prev);
			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_first; 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_first; 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_first; 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_first; 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"

/*  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)
{
#if defined(WIN32) || defined(__CYGWIN__)
	chprintln(ch, "Copyover is disabled under windows.");
#else
	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();

	while (auction_first != NULL)
		reset_auc(auction_first, TRUE);

	save_donation_pit();

	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_first; 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->d_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);

	shutdown_web_server();

	/* 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");
#endif
}

#if !defined(WIN32) && !defined(__CYGWIN__)
/* 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->d_flags = dflags;
		d->host = str_dup(host);
		LINK(d, descriptor_first, descriptor_last, next, prev);
		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_first */
			LINK(d->character, char_first, char_last, next, prev);

			LINK(d->character, player_first, player_last, next_player,
				 prev_player);

			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);

}
#endif

struct qspell_type
{
	SPELL_FUN *spellf;
};

int sn_spellfun_lookup(SPELL_FUN * fun)
{
	int sn;

	for (sn = 0; sn < maxSkill; sn++)
	{
		if (skill_table[sn].spell_fun == fun)
			return sn;
	}
	return -1;
}

const struct qspell_type qspell_table[] = {
	{spell_bless},
	{spell_giant_strength},
	{spell_haste},
	{spell_frenzy},
	{spell_shield},
	{spell_armor},
	{spell_sanctuary},
	{spell_detect_hidden},
	{spell_detect_invis},
	{spell_stone_skin},
	{NULL},
};

CH_CMD(do_spellup)
{
	CHAR_DATA *vch;
	char arg[MIL];
	DESCRIPTOR_DATA *tempdesc;
	int i, sn;

	argument = one_argument(argument, arg);

	if (IS_NULLSTR(arg))
	{
		chprintln(ch, "Syntax: spellup [all, room, <char>]");
		return;
	}

	if (!str_cmp(arg, "all"))
	{
		tempdesc = ch->desc;
		ch->desc = NULL;
		for (vch = player_first; vch != NULL; vch = vch->next_player)
		{
			if (vch == ch || !can_see(ch, vch))
				continue;

			do_function(ch, &do_spellup, vch->name);
		}
		ch->desc = tempdesc;
		chprintln(ch, "OK.");
	}
	else if (!str_cmp(arg, "room"))
	{
		//Lets not spam the caster out
		tempdesc = ch->desc;
		ch->desc = NULL;
		for (vch = ch->in_room->first_person; vch; vch = vch->next_in_room)
		{
			if (vch == ch || IS_NPC(vch) || !can_see(ch, vch))
				continue;

			do_function(ch, &do_spellup, vch->name);
		}
		ch->desc = tempdesc;
		chprintln(ch, "OK.");
	}
	else if ((vch = get_char_world(ch, arg)) != NULL)
	{
		//Lets not spam the caster out
		tempdesc = ch->desc;
		ch->desc = NULL;
		for (i = 0, sn = 0; qspell_table[i].spellf != NULL; i++)
		{
			sn = sn_spellfun_lookup(qspell_table[i].spellf);
			if (sn == -1)
				continue;
			if (is_affected(vch, sn))
				continue;
			qspell_table[i].spellf(sn, get_trust(ch), ch, vch, TARGET_CHAR);
		}
		ch->desc = tempdesc;
		chprintln(ch, "OK.");
	}
	else
		chprintln(ch, "Syntax: spellup [all, room, <char>]");

	return;
}

/** Function: do_pload
  * Descr   : Loads a player object into the mud, bringing them (and their
  *           pet) to you for easy modification.  Player must not be connected.
  *           Note: be sure to send them back when your done with them.
  * Returns : (void)
  * Syntax  : pload (who)
  * Written : v1.0 12/97
  * Author  : Gary McNickle <gary@dharvest.com>
  */
CH_CMD(do_pload)
{
	DESCRIPTOR_DATA d;
	bool isChar = FALSE;
	char name[MAX_INPUT_LENGTH];

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

	argument = one_argument(argument, name);

	/* Dont want to load a second copy of a player who's allready online! */
	if (get_char_world(ch, name) != NULL)
	{
		chprintln(ch, "That person is already connected!");
		return;
	}

	isChar = load_char_obj(&d, capitalize(name));	/* char pfile exists? */

	if (!isChar)
	{
		chprintln(ch, "Load Who? Are you sure? I cant seem to find them.");
		return;
	}

	d.character->desc = NULL;
	LINK(d.character, char_first, char_last, next, prev);
	LINK(d.character, player_first, player_last, next_player, prev_player);
	d.connected = CON_PLAYING;
	reset_char(d.character);

	/* bring player to imm */
	if (d.character->in_room != NULL)
	{
		char_to_room(d.character, ch->in_room);	/* put in room imm is in */
	}

	act("$n has pulled $N from the pattern!", ch, NULL, d.character, TO_ROOM);

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

}

/** Function: do_punload
  * Descr   : Returns a player, previously 'ploaded' back to the void from
  *           whence they came.  This does not work if the player is actually 
  *           connected.
  * Returns : (void)
  * Syntax  : punload (who)
  * Written : v1.0 12/97
  * Author  : Gary McNickle <gary@dharvest.com>
  */
CH_CMD(do_punload)
{
	CHAR_DATA *victim;
	char who[MAX_INPUT_LENGTH];

	argument = one_argument(argument, who);

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

  /** Person is legitametly logged on... was not ploaded.
   */
	if (victim->desc != NULL)
	{
		chprintln(ch, "I dont think that would be a good idea...");
		return;
	}

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

	save_char_obj(victim);
	do_quit(victim, "");

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