roh/conf/area/
roh/game/talk/
roh/help/
roh/monsters/ocean/
roh/objects/ocean/
roh/player/
roh/rooms/area/1/
roh/rooms/misc/
roh/rooms/ocean/
roh/src-2.44b/
/*
 * dm.cpp
 *	 Standard staff functions
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 *	Copyright (C) 2007-2009 Jason Mitchell, Randi Mitchell
 * 	   Contributions by Tim Callahan, Jonathan Hseu
 *  Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman
 *
 */

// C++ includes
#include <sstream>

// Mud Includes
#include "mud.h"
#include "commands.h"
#include "dm.h"
//#include "socket.h"
#include "effects.h"
#include "quests.h"
#include "magic.h"

#include <sstream>
#include <iomanip>
#include <locale>

extern int      controlSock;
long            last_dust_output;
extern long     last_weather_update;



//*********************************************************************
//						dmReboot
//*********************************************************************

int dmReboot(Player* player, cmd* cmnd) {
	bool    resetShips=false;


	if(	!player->isDm() &&
		!(player->flagIsSet(P_CAN_REBOOT) &&
		player->getClass() == CARETAKER)
	)
		return(cmdNoAuth(player));

	if(cmnd->num==2 &&  !strcmp(cmnd->str[1], "-ships"))
		resetShips = true;

	player->print("Rebooting now!\n");
	logn("log.bane", "Reboot by %s.\n", player->name);
	broadcast("### Going for a reboot, hang onto your seats!");
	if(resetShips)
		player->print("Resetting game time to midnight, updating ships...\n");
	gServer->processOutput();
	loge("--- Attempting game reboot ---\n");
	gConfig->resaveAllRooms(0);

	gServer->startReboot(resetShips);

	merror("dmReboot failed!!!", FATAL);
	return(0);

}

//*********************************************************************
//						dmMobInventory
//*********************************************************************

int dmMobInventory(Player* player, cmd* cmnd) {
	Monster	*monster=0;
	Object	*object;
	otag	*op=0;
	char	str[2048];
	int		count=0, i=0;

	if(!player->canBuildMonsters())
		return(cmdNoAuth(player));


	if(cmnd->num < 2) {
		player->print("Which monster?\n");
		return(0);
	}

	monster = player->getRoom()->findMonster(player, cmnd);
	if(!monster) {
		player->print("That's not here.\n");
		return(0);
	}



	if(!strcmp(cmnd->str[2], "-l") || player->getClass() == BUILDER) {
		player->print("Items %s will possibly drop:\n", monster->name);
		for(i=0;i<10;i++) {
			if(!monster->carry[i].info.id) {
				player->print("Carry slot %d: %sNothing.\n", i+1, i < 9 ? " " : "");
				continue;
			}

			if(!loadObject(monster->carry[i].info, &object))
				continue;
			if(!object)
				continue;

			if(player->getClass() == BUILDER && player->checkRangeRestrict(object->info))
				player->print("Carry slot %d: %sout of range(%s).\n", i+1, i < 9 ? " " : "", object->info.str().c_str());
			else
				player->printColor("Carry slot %d: %s%s(%s).\n", i+1, i < 9 ? " " : "", object->name, object->info.str().c_str());

			delete object;
		}

		return(0);
	}


	sprintf(str, "%s%s is carrying: ", (monster->flagIsSet(M_NO_PREFIX) ? "":"The "), monster->name);

	op = monster->first_obj;
	while(op) {
		count++;
		strcat(str, op->obj->name);
		strcat(str, "^x");
		if(op->obj->flagIsSet(O_NOT_PEEKABLE))
			strcat(str, "(NoPeek)");
		if(op->obj->flagIsSet(O_NO_STEAL))
			strcat(str, "(NoSteal)");
		if(op->obj->flagIsSet(O_BODYPART))
			strcat(str, "(BodyPart)");
		strcat(str, ", ");

		op = op->next_tag;
	}

	if(!count)
		strcat(str, "Nothing.");
	else {
		str[strlen(str) - 2] = '.';
		str[strlen(str) - 1] = 0;
	}

	player->printColor("%s\n", str);

	return(0);
}

//*********************************************************************
//						dmSockets
//*********************************************************************

int dmSockets(Player* player, cmd* cmnd) {
	int num=0;

	player->print("Connected Sockets:\n");

	foreach(Socket* sock, gServer->sockets) {
		num += 1;
		player->print("Fd: %-2d   %s\n", sock->getFd(), sock->getHostname().c_str());
	}
	player->print("%d total connection%s.\n", num, num != 1 ? "s" : "");
	return(PROMPT);
}




//*********************************************************************
//						dmLoadSave
//*********************************************************************
// handles loading and saving of a bunch of config files

int dmLoadSave(Player* player, cmd* cmnd, bool load) {
	if(cmnd->num < 2) {
		player->print("*dmload / *dmsave supports the following options:\n");
		player->printColor("^yLOAD:\n");
		player->print("   areas         bans\n");
		player->print("   calendar      catrefinfo\n");
		player->print("   config        classes\n");
		player->print("   clans         deities\n");
		player->print("   faction       fishing\n");
		player->print("   flags         guilds\n");
		player->print("   limited       properties\n");
		player->print("   quests        races\n");
		player->print("   recipes       ships\n");
		player->print("   skills        spells\n");
		player->printColor("   spl ^c[spell id]\n");
		player->print("   startlocs\n");
		player->printColor("^ySAVE:\n");
		player->print("   bans          config\n");
		player->print("   guilds        limited\n");
		player->print("   properties    recipes\n");
		player->print("   spells\n");
		player->print("\n");
		return(0);
	}

	if(!strcmp(cmnd->str[1], "bans")) {
		if(load) {
			gConfig->loadBans();
			player->print("Bans reloaded.\n");
			dmListbans(player, NULL);
		} else {
			gConfig->saveBans();
			player->print("Bans saved.\n");
		}
	} else if(!strcmp(cmnd->str[1], "config")) {
		if(load) {
			player->print("Reloading configuration file.\n");
			gConfig->loadConfig();
		} else {
			player->print("Saving configuration file.\n");
			gConfig->saveConfig();
		}
	} else if(!strcmp(cmnd->str[1], "guilds")) {
		if(load) {
			player->print("Reloading guilds.\n");
			gConfig->loadGuilds();
		} else {
			player->print("Saving guilds.\n");
			gConfig->saveGuilds();
		}
	} else if(!strcmp(cmnd->str[1], "recipes")) {
		if(load) {
			gConfig->loadRecipes();
			player->print("Recipes reloaded.\n");
		} else {
			gConfig->saveRecipes();
			player->print("Recipes saved.\n");
		}
	} else if(!strcmp(cmnd->str[1], "properties")) {
		if(load) {
			gConfig->loadProperties();
			player->print("Properties reloaded.\n");
		} else {
			gConfig->saveProperties();
			player->print("Properties saved.\n");
		}
	} else if(!strcmp(cmnd->str[1], "limited")) {
		if(load) {
			gConfig->loadLimited();
			player->print("Limited items reloaded.\n");
		} else {
			gConfig->saveLimited();
			player->print("Limited items saved.\n");
		}
	} else if(!strcmp(cmnd->str[1], "spells")) {
		if(load) {
			gConfig->loadSpellList();
			player->print("Spell list reloaded.\n");
		} else {
			gConfig->saveSpellList();
			player->print("Spell list saved.\n");
		}
	} else if(!strcmp(cmnd->str[1], "areas") && load) {
		if(!strcmp(cmnd->str[2], "confirm")) {

			std::list<Area*>::iterator at;
			std::map<bstring, AreaRoom*>::iterator it;
			AreaRoom* aRoom = 0;

			for(at = gConfig->areas.begin() ; at != gConfig->areas.end() ; at++) {
				for(it = (*at)->rooms.begin() ; it != (*at)->rooms.end() ; it++) {
					aRoom = (*it).second;
					aRoom->setStayInMemory(true);
					aRoom->expelPlayers();
				}
			}

			gConfig->loadAreas();
			player->print("Area reloaded.\n");
		} else {
			player->print("This will expel all current players in the overland to their recall rooms.\n");
			player->printColor("Type ^y*dmload areas confirm^x to continue.\n");
		}
	} else if(!strcmp(cmnd->str[1], "quests") && load) {
		gConfig->loadQuestTable();
		gConfig->loadQuests();
		gConfig->resetParentQuests();
		player->print("Quests reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "clans") && load) {
		gConfig->loadClans();
		player->print("Clans reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "classes") && load) {
		gConfig->loadClasses();
		player->print("Classes reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "races") && load) {
		gConfig->loadRaces();
		player->print("Races reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "deities") && load) {
		gConfig->loadDeities();
		player->print("Deities reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "skills") && load) {
		gConfig->loadSkills();
		player->print("Skills reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "startlocs") && load) {
		gConfig->loadStartLoc();
		player->print("StartLocs reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "catrefinfo") && load) {
		gConfig->loadCatRefInfo();
		player->print("CatRefInfo reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "flags") && load) {
		gConfig->loadFlags();
		player->print("Flags reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "faction") && load) {
		gConfig->loadFactions();
		player->print("Factions reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "fishing") && load) {
		gConfig->loadFishing();
		player->print("Fishing reloaded.\n");
	} else if(!strcmp(cmnd->str[1], "spl") && load) {
		SpellInfo* spell=0;
		if(cmnd->str[2][0]) {
			std::map<bstring, SpellInfo>::iterator it = gConfig->spells.find(cmnd->str[2]);
			if(it != gConfig->spells.end())
				spell = &(*it).second;
		}
		if(!spell) {
			player->print("Spell id \"%s\" not found.\n", cmnd->str[2]);
		} else {
			bool success = spell->loadScript();
			player->print("Reloading spell \"%s\" %s.\n", spell->id.c_str(),
				success ? "was successful" : "failed");
		}
	} else if(!strcmp(cmnd->str[1], "calendar") && load) {
		reloadCalendar(player);
	} else {
		player->print("Invalid request!\n");
		cmnd->num = 1;
		dmLoadSave(player, cmnd, load);
	}

	return(0);
}

//*********************************************************************
//						dmLoad
//*********************************************************************
// a wrapper

int dmLoad(Player* player, cmd* cmnd) {

	if(!strcmp(cmnd->str[0], "*banload")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "ban");
	} else if(!strcmp(cmnd->str[0], "*guildload")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "guild");
	} else if(!strcmp(cmnd->str[0], "*questload")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "quest");
	} else if(!strcmp(cmnd->str[0], "*clanload")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "clan");
	} else if(!strcmp(cmnd->str[0], "*exitload")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "exit");
	} else if(!strcmp(cmnd->str[0], "*recload")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "recipes");
	}

	dmLoadSave(player, cmnd, true);
	return(0);
}

//*********************************************************************
//						dmSave
//*********************************************************************
// a wrapper

int dmSave(Player* player, cmd* cmnd) {

	if(!strcmp(cmnd->str[0], "*bansave")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "ban");
	} else if(!strcmp(cmnd->str[0], "*guildsave")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "guild");
	} else if(!strcmp(cmnd->str[0], "*questsave")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "quest");
	} else if(!strcmp(cmnd->str[0], "*clansave")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "clan");
	} else if(!strcmp(cmnd->str[0], "*recsave")) {
		cmnd->num = 2;
		strcpy(cmnd->str[1], "recipes");
	}

	dmLoadSave(player, cmnd, false);
	return(0);
}

//*********************************************************************
//						dmTeleport
//*********************************************************************
// This function allows staff to teleport to a given room number, or to
// a player's location.  It will also teleport a player to the DM or
// one player to another.

void Player::dmPoof(BaseRoom* room, BaseRoom *newRoom) {
	if(flagIsSet(P_ALIASING)) {
		alias_crt->deleteFromRoom();
		broadcast(getSock(), room, "%M just wandered away.", alias_crt);
		if(newRoom)
			alias_crt->addToRoom(newRoom);
	}

	if(flagIsSet(P_DM_INVIS)) {
		if(isDm())
			broadcast(::isDm, getSock(), room, "*DM* %s disappears in a puff of smoke.", name);
		if(cClass == CARETAKER)
			broadcast(::isCt, getSock(), room, "*DM* %s disappears in a puff of smoke.", name);
		if(!isCt())
			broadcast(::isStaff, getSock(), room, "*DM* %s disappears in a puff of smoke.", name);
	} else {
		broadcast(getSock(), room, "%M disappears in a puff of smoke.", this);
	}
}

int dmTeleport(Player* player, cmd* cmnd) {
	BaseRoom	*room=0, *old_room=0;
	Room		*uRoom=0;
	Creature	*creature=0;
	Player		*target=0, *target2=0;

	Location	l;


	// *t 1 and *t 1.-10.7 will trigger num < 2,
	// *t misc.100 will not, so we need to make an exception
	bstring str = getFullstrText(cmnd->fullstr, 1);
	bstring txt = getFullstrText(str, 1, '.');

	// set default *t room
	if(str == "") {
		if(player->getClass() == BUILDER && player->room.isArea(gConfig->defaultArea))
			l.room.id = ROOM_BUILDER_PERM_LOW;
		else
			l = player->getRecallRoom();

		if(player->area_room && l.mapmarker == player->area_room->mapmarker) {
			player->print("You are already there!\n");
			return(0);
		}

		room = 	l.loadRoom();
	} else if(cmnd->num < 2 || (txt != "" && txt.getAt(0))) {
		Area		*area=0;

		getDestination(str, &l, player);

		if(player->getClass() != BUILDER && l.mapmarker.getArea()) {
			if(player->area_room && l.mapmarker == player->area_room->mapmarker) {
				player->print("You are already there!\n");
				return(0);
			}

			area = gConfig->getArea(l.mapmarker.getArea());
			if(!area) {
				player->print("Area does not exist.\n");
				return(0);
			}

			// pointer to old room
			player->dmPoof(player->getRoom(), 0);
			area->move(player, &l.mapmarker);
			// manual
			if(player->flagIsSet(P_ALIASING))
				player->getAlias()->addToRoom(player->getRoom());
			return(0);
		}


		if(!validRoomId(l.room)) {
			player->print("Error: out of range.\n");
			return(0);
		}
		if(!loadRoom(l.room, &uRoom)) {
			player->print("Error (%s)\n", l.str().c_str());
			return(0);
		}

		if(!player->checkBuilder(l.room))
			return(0);

		room = uRoom;

	} else if(cmnd->num < 3) {

		lowercize(cmnd->str[1], 1);
		creature = gServer->findPlayer(cmnd->str[1]);
		if(!creature || creature == player || !player->canSee(creature)) {
			player->print("%s is not on.\n", cmnd->str[1]);
			return(0);
		}

		if(player->getClass() == BUILDER && creature->getClass() != BUILDER) {
			player->print("You are only allowed to teleport to other builder.\n");
			return(0);
		}


		old_room = player->getRoom();
		room = creature->getRoom();

		player->dmPoof(old_room, room);

		player->deleteFromRoom();
		player->addToSameRoom(creature);
		player->doFollow();
		return(0);

	} else {
		if(!player->isCt()) {
			player->print("You are not allowed to teleport others to you.\n");
			return(0);
		}

		lowercize(cmnd->str[1], 1);
		target = gServer->findPlayer(cmnd->str[1]);
		if(!target || target == player || !player->canSee(target)) {
			player->print("%s is not on.\n", cmnd->str[1]);
			return(0);
		}
		lowercize(cmnd->str[2], 1);
		if(*cmnd->str[2] == '.')
			target2 = player;
		else
			target2 = gServer->findPlayer(cmnd->str[2]);
		if(!target2) {
			player->print("%s is not on.\n", cmnd->str[1]);
			return(0);
		}
		if(target ==  target2) {
			player->print("You cant do that.\n");
			return(0);
		}


		old_room = target->getRoom();
		room = target2->getRoom();

		target->dmPoof(old_room, room);

		target->deleteFromRoom();
		target->addToSameRoom(target2);
		target->doPetFollow();
		return(0);
	}

	old_room = player->getRoom();

	player->dmPoof(old_room, room);

	player->deleteFromRoom();
	player->addToRoom(room);
	player->doFollow();

	return(0);
}


//*********************************************************************
//						dmUsers
//*********************************************************************
// This function allows staff to list all users online, displaying
// level, name, current room # and name, and address.

int dmUsers(Player* player, cmd* cmnd) {
	long	t = time(0);
	bool	full=false;
	bstring tmp="", host="";
	Player* user=0;
	//Socket* sock=0;

	std::ostringstream oStr;
	char	str[100];
	oStr.setf(std::ios::left, std::ios::adjustfield);
	oStr.imbue(std::locale(""));

	bstring cr = gConfig->defaultArea;
	if(player->parent_rom)
		cr = player->parent_rom->info.area;

	if(cmnd->num > 1 && cmnd->str[1][0] == 'f')
		full = true;

	oStr << "^bLev  Clas  Player     ";
	if(full)
		oStr << "Address                                                    Idle";
	else
		oStr << "Room                 Address             Last Command      Idle";
	oStr << "\n---------------------------------------------------------------------------------------\n";

	//std::pair<bstring, Player*> p;
	foreach(Socket* sock, gServer->sockets) {
		//user = p.second;
		//sock = user->getSock();
		user = sock->getPlayer();

		if(!user || !player->canSee(user))
			continue;

		host = sock->getHostname();
		if(user->isDm() && !player->isDm())
			host = "mud.rohonline.net";

		oStr.setf(std::ios::right, std::ios::adjustfield);
		oStr << "^x[" << std::setw(2) << user->getLevel() << "] ";
		oStr.setf(std::ios::left, std::ios::adjustfield);

		if(user->isStaff())
			oStr << "^g";
		oStr << std::setw(4) << bstring(getShortClassName(user)).left(4) << "^w ";

		if(!user->flagIsSet(P_SECURITY_CHECK_OK))
			oStr << "^r";
		else
			oStr << "^y";

		if(user->flagIsSet(P_DM_INVIS))
			oStr << "+";
		else if(user->flagIsSet(P_INCOGNITO))
			oStr << "g";
		else if(user->isInvisible())
			oStr << "*";
		else
			oStr << " ";

		if(user->flagIsSet(P_OUTLAW))
			oStr << "^R";
		else if(user->flagIsSet(P_LINKDEAD))
			oStr << "^G";
		else if(user->flagIsSet(P_WATCHER))
			oStr << "^w";
		else if(user->flagIsSet(P_GLOBAL_GAG))
			oStr << "^m";

		oStr << std::setw(10) << bstring(user->name).left(10) << "^w ";

		if(!sock->isConnected()) {
			sprintf(str, "connecting (Fd: %d)", sock->getFd());
			oStr << "^Y" << std::setw(20) << str << " ^c" << std::setw(37) << host.left(37);
		} else if(full) {
			oStr << "^m" << std::setw(58) << host.left(58);
		} else {
			if(user->parent_rom) {
				sprintf(str, "%s: ^b%s", user->parent_rom->info.str(cr, 'b').c_str(), bstring(user->parent_rom->name).c_str());
				oStr << std::setw(22 + (str[0] == '^' ? 4 : 0)) << bstring(str).left(22 + (str[0] == '^' ? 4 : 0));
			} else {
				//sprintf(str, "%s", user->area_room->mapmarker.str(true).c_str());
				//oStr << std::setw(26) << bstring(str).left(26);
				oStr << std::setw(38) << user->area_room->mapmarker.str(true).left(38);
			}


			oStr << " ^c" << std::setw(19) << host.left(19)
				 << " ^g";
			if(!user->isDm() || player->isDm())
				oStr << std::setw(17) << dmLastCommand(user).left(17);
			else
				oStr << std::setw(17) << "l";
		}

		sprintf(str, "%02ld:%02ld", (t-sock->ltime)/60L, (t-sock->ltime)%60L);
		oStr << " ^w" << str << "\n";
	}

	player->printColor("%s", oStr.str().c_str());
	player->hasNewMudmail();
	player->print("\n");

	return(0);
}

//*********************************************************************
//						dmFlushSave
//*********************************************************************
// This function allows staff to save all the rooms in memory back to
// disk in one fell swoop.

int dmFlushSave(Player* player, cmd* cmnd) {
	if(cmnd->num < 2) {
		player->print("All rooms and contents flushed to disk.\n");
		gConfig->resaveAllRooms(0);
	} else {
		player->print("All rooms and PERM contents flushed to disk.\n");
		gConfig->resaveAllRooms(PERMONLY);
	}
	return(0);
}

//*********************************************************************
//						dmShutdown
//*********************************************************************
// This function allows staff to shut down the game in a given number of
// minutes.

int dmShutdown(Player* player, cmd* cmnd) {
	player->print("Ok.\n");

	log_immort(true, player, "*** Shutdown by %s.\n", player->name);

	Shutdown.ltime = time(0);
	Shutdown.interval = cmnd->val[0] * 60 + 1;

	return(0);
}

//*********************************************************************
//						dmFlushCrtObj
//*********************************************************************
// This function allows staff to flush the object and creature data so
//  that updated data can be loaded into memory instead.

int dmFlushCrtObj(Player* player, cmd* cmnd) {

	if(!player->canBuildObjects() && !player->canBuildMonsters())
		return(cmdNoAuth(player));

	if(player->canBuildObjects())
		gConfig->flushObject();
	if(player->canBuildMonsters())
		gConfig->flushMonster();

	player->print("Basic object and monster data flushed from memory.\n");
	return(0);
}



//*********************************************************************
//						dmResave
//*********************************************************************
// This function allows staff to save a room back to disk.

int dmResave(Player* player, cmd* cmnd) {
	int		s=0;

	if(!player->builderCanEditRoom("use *save"))
		return(0);

	if(	cmnd->num > 1 &&
		(!strcmp(cmnd->str[1], "c") || !strcmp(cmnd->str[1], "o"))
	) {
		bstring str = getFullstrText(cmnd->fullstr, 3);
		if(str == "") {
			player->print("Syntax: *save %c [name] [number]\n", cmnd->str[1]);
			return(0);
		}

		CatRef	cr;
		getCatRef(str, &cr, player);

		if(!strcmp(cmnd->str[1], "c"))
			dmSaveMob(player, cmnd, cr);
		else if(!strcmp(cmnd->str[1], "o"))
			dmSaveObj(player, cmnd, cr);
		return(0);
	}


	if(!player->checkBuilder(player->parent_rom)) {
		player->print("Error: this room is out of your range; you cannot save this room.\n");
		return(0);
	}


	if(player->parent_rom) {

		s = gConfig->resaveRoom(player->parent_rom->info);
		if(s < 0)
			player->print("Resave failed. Tell this number to Bane: (%d)\n",s);
		else
			player->print("Room saved.\n");

	} else if(player->area_room) {

		player->area_room->save(player);

	} else
		player->print("Nothing to save!\n");

	return(0);
}

//*********************************************************************
//						dmPerm
//*********************************************************************
// This function allows staff to make a given object sitting on the
// floor into a permanent object.

int dmPerm(Player* player, cmd* cmnd) {
	std::map<int, crlasttime>::iterator it;
	Monster* target=0;
	Object	*object=0;
	int		x=0;

	if(!player->canBuildMonsters() && !player->canBuildObjects())
		return(cmdNoAuth(player));

	if(!player->checkBuilder(player->parent_rom)) {
		player->print("Room number not in any of your alotted ranges.\n");
		return(0);
	}
	if(!player->builderCanEditRoom("use *perm"))
		return(0);

	if(!needUniqueRoom(player))
		return(0);

	if(cmnd->num < 2) {
		player->print("Syntax: *perm [o|c|t] [name|d|exit] [timeout|slot]\n");
		return(0);
	}

	switch(low(cmnd->str[1][0])) {
	case 'o':

		if(!player->canBuildObjects()) {
			player->print("Error: you cannot perm objects.\n");
			return(PROMPT);
		}

		if(!strcmp(cmnd->str[2], "d") && strlen(cmnd->str[2])<2) {
			if(cmnd->val[2] > NUM_PERM_SLOTS || cmnd->val[2] < 1) {
				player->print("Slot to delete out of range.\n");
				return(0);
			}

			it = player->parent_rom->permObjects.find(cmnd->val[2]-1);
			if(it != player->parent_rom->permObjects.end()) {
				player->parent_rom->permObjects.erase(it);
				player->print("Perm Object slot #%d cleared.\n", cmnd->val[2]);
			} else {
				player->print("Perm object slot #%d already empty.\n", cmnd->val[2]);
			}

			return(0);
		}


		object = findObject(player, player->parent_rom->first_obj, cmnd->str[2], 1);

		if(!object) {
			player->print("Object not found.\n");
			return(0);
		}

		if(!object->info.id) {
			player->print("Object is not in database. Not permed.\n");
			return(0);
		}

		if(cmnd->val[2] < 2)
			cmnd->val[2] = 7200;

		x = player->parent_rom->permObjects.size();
		if(x > NUM_PERM_SLOTS) {
			player->print("Room is already full.\n");
			return(0);
		}

		player->parent_rom->permObjects[x].cr = object->info;
		player->parent_rom->permObjects[x].interval = (long)cmnd->val[2];

		log_immort(true, player, "%s permed %s^g in room %s.\n", player->name,
			object->name, player->parent_rom->info.str().c_str());

		player->printColor("%s^x (%s) permed with timeout of %d.\n", object->name, object->info.str().c_str(), cmnd->val[2]);

		return(0);
		// perm Creature
	case 'c':

		if(!player->canBuildMonsters()) {
			player->print("Error: you cannot perm mobs.\n");
			return(PROMPT);
		}

		if(!strcmp(cmnd->str[2], "d") && strlen(cmnd->str[2])<2) {
			if(cmnd->val[2] > NUM_PERM_SLOTS || cmnd->val[2] < 1) {
				player->print("Slot to delete out of range.\n");
				return(0);
			}

			it = player->parent_rom->permMonsters.find(cmnd->val[2]-1);
			if(it != player->parent_rom->permMonsters.end()) {
				player->parent_rom->permMonsters.erase(it);
				player->print("Perm monster slot #%d cleared.\n", cmnd->val[2]);
			} else {
				player->print("Perm monster slot #%d already empty.\n", cmnd->val[2]);
			}

			return(0);
		}

		target = player->parent_rom->findMonster(player, cmnd->str[2], 1);
		if(!target) {
			player->print("Creature not found.\n");
			return(0);
		}



		if(!target->info.id) {
			player->print("Monster is not in database. Not permed.\n");
			return(0);
		}
		if(!player->checkBuilder(target->info)) {
			player->print("Monster number not in any of your alotted ranges.\n");
			return(0);
		}

		if(cmnd->val[2] < 2)
			cmnd->val[2] = 7200;

		x = player->parent_rom->permMonsters.size();
		if(x > NUM_PERM_SLOTS) {
			player->print("Room is already full.\n");
			return(0);
		}

		player->parent_rom->permMonsters[x].cr = target->info;
		player->parent_rom->permMonsters[x].interval = (long)cmnd->val[2];

		log_immort(true, player, "%s permed %s in room %s.\n", player->name,
			target->name, player->parent_rom->info.str().c_str());

		player->print("%s (%s) permed with timeout of %d.\n", target->name, target->info.str().c_str(), cmnd->val[2]);

		return(0);
		// perm tracks
	case 't':
		if(!strcmp(cmnd->str[2], "d") || cmnd->num < 3) {
			player->parent_rom->clearFlag(R_PERMENANT_TRACKS);
			player->print("Perm tracks deleted.\n");
			return(0);
		}
		player->parent_rom->track.setDirection(cmnd->str[2]);
		player->parent_rom->setFlag(R_PERMENANT_TRACKS);
		player->print("Perm tracks added leading %s.\n", player->parent_rom->track.getDirection().c_str());
		return(0);

	default:
		player->print("Syntax: *perm [o|c|t] [name|d|exit] [timeout|slot]\n");
		return(0);
	}
}

//*********************************************************************
//						dmInvis
//*********************************************************************
// This function allows staff to turn themself invisible.

int dmInvis(Player* player, cmd* cmnd) {

	if(player->flagIsSet(P_DM_INVIS)) {
		if(!player->builderCanEditRoom("turn off invis"))
			return(0);
		player->clearFlag(P_DM_INVIS);
		player->printColor("^mInvisibility off.\n");
	} else {
		player->setFlag(P_DM_INVIS);
		player->printColor("^yInvisibility on.\n");
	}
	return(0);
}


//*********************************************************************
//						dmIncog
//*********************************************************************

int dmIncog(Player* player, cmd* cmnd) {

	if(player->flagIsSet(P_INCOGNITO)) {
		if(!player->isCt()) {
			player->print("You cannot unlock your presence.\n");
		} else {
			player->clearFlag(P_INCOGNITO);
			player->printColor("^gYou unlock your presence.\n");
		}
	} else {
		player->setFlag(P_INCOGNITO);
		player->printColor("^gYou cloak your pressence.\n");
	}
	return(0);
}

//*********************************************************************
//						dmAc
//*********************************************************************
// This function allows staff to take a look at their own special stats.
// or another user's stats.

int dmAc(Player* player, cmd* cmnd) {
	Player	*target=0;

	if(cmnd->num == 2) {
		lowercize(cmnd->str[1], 1);
		target = gServer->findPlayer(cmnd->str[1]);
		if(!target || !player->canSee(target)) {
			player->print("%s is not on.\n", cmnd->str[1]);
			return(0);
		}
	} else {
		player->hp.restore();
		player->mp.restore();
		target = player;
	}

	player->print("WeaponSkill: %d  Defense Skill: %d  Armor: %d(%.0f%%)\n",
			target->getWeaponSkill(player->ready[WIELD-1]), target->getDefenseSkill(),  target->getArmor(), (target->getDamageReduction(target)*100.0));
	return(0);
}

//*********************************************************************
//						dmWipe
//*********************************************************************

int dmWipe(Player* player, cmd* cmnd) {
//	Room* room=0;
	//	ctag	*cp;
	//otag	*op;
//	int		a=0, fd = player->fd, low=0, high=0;

	// disabled for now
	return(cmdNoAuth(player));
#if 0
	if(cmnd->num < 2) {
		player->print("Usage: *wipe r (low#) r (high#)\n");
		return(0);
	}

	if(cmnd->str[1][0] != 'r' || cmnd->str[2][0] != 'r') {
		player->print("Usage: *wipe r (low#) r (high#)\n");
		return(0);
	}

	low = cmnd->val[1];
	high = cmnd->val[2];

	if(low == high) {
		player->print("Low and high number cannot be the same thing.\n");
		return(0);
	}

	if(low < 1 || high < 1) {
		player->print("Positive numbers....\n");
		return(0);
	}

	if(low > high) {
		player->print("Usage: *wipe r (low#) r (high#)\n");
		return(0);
	}

	for(a=low; a<high+1; a++) {
		if(a == player->room.id) {
			player->printColor("^rCURRENT ROOM SKIPPED.\n");
			continue;
		}

		loadRoom(a, &room);

		if(!room) {
			player->print("ALLOCATION ERROR!\n");
			continue;
		}


		resave_rom(a);
		player->print("Room %d cleared and saved.\n", a);
		//delete room;

	}

	return(0);
#endif
}



//*********************************************************************
//						dmListFlags
//*********************************************************************

int dmListFlags(Player* player, cmd* cmnd) {
	int		i=0, max=0;
	bool	highlight=false;

	const char* (*lookup_flag)(int) = NULL;


	if(cmnd->num < 2) {
		player->print("List what flags?\n    [mon | obj | room | player | exit]\n");
		return(0);
	}

	if(!strcasecmp(cmnd->str[1], "mon")) {
		player->print("Monster");
		lookup_flag = get_mflag;
		max = MAX_MONSTER_FLAGS;
	} else if(!strcasecmp(cmnd->str[1], "obj")) {
		player->print("Object");
		lookup_flag = get_oflag;
		max = MAX_OBJECT_FLAGS;
	} else if(!strcasecmp(cmnd->str[1], "room")) {
		player->print("Room");
		lookup_flag = get_rflag;
		max = MAX_ROOM_FLAGS;
	} else if(!strcasecmp(cmnd->str[1], "player")) {
		if(player->getClass()==BUILDER) {
			player->print("You are not allowed to view player flags.\n");
			return(0);
		}
		player->print("Player");
		lookup_flag = get_pflag;
		max = MAX_PLAYER_FLAGS;
	} else if(!strcasecmp(cmnd->str[1], "exit")) {
		player->print("Exit");
		lookup_flag = get_xflag;
		max = MAX_EXIT_FLAGS;
	} else {
		player->print("Invalid flag type!\n    [mon | obj | room | player | exit]\n");
		return(0);
	}

	player->print(" Flags:\n");

	for(i=0;i<max;i++) {
		highlight = !strcmp(lookup_flag(i), "Unused");
		player->printColor("[%d].........%s%s\n", i+1, highlight ? "^y" : "", lookup_flag(i));
	}

	player->print("\n");
	return(0);
}



/*************************************************************************
*  This function allows the deletion of the database.
*
*/
// TODO: -- REDO THIS to work with xml, easy enough to do.
int dmDeleteDb(Player* player, cmd* cmnd) {
//	int 		fd = player->fd, index, blah=0;

	if(cmnd->num < 2) {
		player->print("Syntax: *clear [o|c] [index]\n");
		return(0);
	}
	player->print("Currently disabled\n");
	return(0);

}
//*********************************************************************
//						dmGameStatus
//*********************************************************************
// Show the status of all configurable options in the game.

int dmGameStatus(Player* player, cmd* cmnd) {
	char **d;
	char buf[2048];

	if(cmnd->num == 2 && !strcmp(cmnd->str[1], "r")) {
		gConfig->load();
		player->print("Config Reloaded.\n");
		return(0);
	} else if(cmnd->num == 2 && !strcmp(cmnd->str[1], "s")) {
		gConfig->save();
		player->print("Config Saved.\n");
		return(0);
	}


	player->printColor("^B\n\nGame Variable Status\n");
	player->printColor("^CGame Port: %d      PID: %d\n\n",gConfig->getPortNum(), getpid());
	player->printColor("^cDMs here are: ");
	strcpy(buf,"");
	d = dmname;
	while(*d) {
		strcat(buf, *d);
		strcat(buf, ", ");
		d++;
	}
	strcpy(buf+strlen(buf)-2, ".\n");
	player->printColor(buf);
	player->printColor("^cDM password: ^x%s\n", gConfig->getDmPass().c_str());
	player->printColor("^cWebserver:   ^x%s\n", gConfig->getWebserver().c_str());
	player->printColor("^cUser Agent:  ^x%s\n", gConfig->getUserAgent().c_str());

	/*	player->printColor("^cQuestions email address    : ");
	player->printColor("%s\n", questions_to_email);
	player->printColor("^cAuthorization email address: ");
	player->printColor("%s\n", auth_questions_email);
	player->printColor("^cRegistrations email address: ");
	player->printColor("%s\n", register_questions_email); */
	player->printColor("\n");
	player->printColor("^BLottery Information\n");
	player->printColor("^CLottery Enabled:         %3s\n", iToYesNo(gConfig->getLotteryEnabled()));
	player->printColor("^cCurrent lottery cycle:   %d\n", gConfig->getCurrentLotteryCycle());
	player->printColor("^cCurrent ticket price:    %d\n", gConfig->getLotteryTicketPrice());
	player->printColor("^cCurrent lottery jackpot: %ld\n", gConfig->getLotteryJackpot());
	short numbers[6];
	gConfig->getNumbers(numbers);
	player->printColor("^cLast Winning Numbers:    ");
	player->printColor("%02d %02d %02d %02d %02d  (%02d)\n", numbers[0], numbers[1], numbers[2],
			numbers[3], numbers[4], numbers[5]);

	player->printColor("\n");

	player->printColor("^B\nSettings\n");
	player->printColor("^cCheckdouble      = %-3s     ", iToYesNo(gConfig->checkDouble));
	player->printColor("^cNopkillcombat    = %-3s\n", iToYesNo(getPkillInCombatDisabled()));
	player->printColor("^cAprilFools       = %-3s     ", iToYesNo(gConfig->willAprilFools()));
	player->printColor("^cFlashPolicyPort  = %d\n", gConfig->getFlashPolicyPort());

	player->printColor("^cShopNumObjects   = %-4d    ", gConfig->getShopNumObjects());
	player->printColor("^cShopNumLines     = %d\n", gConfig->getShopNumLines());

	player->printColor("^cTxtOnCrash       = %-3s     ", iToYesNo(gConfig->sendTxtOnCrash()));
	player->print("\n");

	return(0);
}


//*********************************************************************
//						dmWeather
//*********************************************************************

int dmWeather(Player* player, cmd* cmnd) {
	BaseRoom* room = player->getRoom();
	player->printColor("^BWeather Strings: note that these strings may be specific to this room.\n");
	player->printColor("^cSunrise: ^x%s\n", gConfig->weatherize(WEATHER_SUNRISE, room).c_str());
	player->printColor("^cSunset: ^x%s\n", gConfig->weatherize(WEATHER_SUNSET, room).c_str());
	player->printColor("^cEarth Trembles: ^x%s\n", gConfig->weatherize(WEATHER_EARTH_TREMBLES, room).c_str());
	player->printColor("^cHeavy Fog: ^x%s\n", gConfig->weatherize(WEATHER_HEAVY_FOG, room).c_str());
	player->printColor("^cBeautiful Day: ^x%s\n", gConfig->weatherize(WEATHER_BEAUTIFUL_DAY, room).c_str());
	player->printColor("^cBright Sun: ^x%s\n", gConfig->weatherize(WEATHER_BRIGHT_SUN, room).c_str());
	player->printColor("^cGlaring Sun: ^x%s\n", gConfig->weatherize(WEATHER_GLARING_SUN, room).c_str());
	player->printColor("^cHeat: ^x%s\n", gConfig->weatherize(WEATHER_HEAT, room).c_str());
	player->printColor("^cStill: ^x%s\n", gConfig->weatherize(WEATHER_STILL, room).c_str());
	player->printColor("^cLight Breeze: ^x%s\n", gConfig->weatherize(WEATHER_LIGHT_BREEZE, room).c_str());
	player->printColor("^cStrong Wind: ^x%s\n", gConfig->weatherize(WEATHER_STRONG_WIND, room).c_str());
	player->printColor("^cWind Gusts: ^x%s\n", gConfig->weatherize(WEATHER_WIND_GUSTS, room).c_str());
	player->printColor("^cGale Force: ^x%s\n", gConfig->weatherize(WEATHER_GALE_FORCE, room).c_str());
	player->printColor("^cClear Skies: ^x%s\n", gConfig->weatherize(WEATHER_CLEAR_SKIES, room).c_str());
	player->printColor("^cLight Clouds: ^x%s\n", gConfig->weatherize(WEATHER_LIGHT_CLOUDS, room).c_str());
	player->printColor("^cThunderheads: ^x%s\n", gConfig->weatherize(WEATHER_THUNDERHEADS, room).c_str());
	player->printColor("^cLight Rain : ^x%s\n", gConfig->weatherize(WEATHER_LIGHT_RAIN, room).c_str());
	player->printColor("^cHeavy Rain: ^x%s\n", gConfig->weatherize(WEATHER_HEAVY_RAIN, room).c_str());
	player->printColor("^cSheets Rain: ^x%s\n", gConfig->weatherize(WEATHER_SHEETS_RAIN, room).c_str());
	player->printColor("^cTorrent Rain: ^x%s\n", gConfig->weatherize(WEATHER_TORRENT_RAIN, room).c_str());
	player->printColor("^cNo Moon: ^x%s\n", gConfig->weatherize(WEATHER_NO_MOON, room).c_str());
	player->printColor("^cSliver Moon: ^x%s\n", gConfig->weatherize(WEATHER_SLIVER_MOON, room).c_str());
	player->printColor("^cHalf Moon: ^x%s\n", gConfig->weatherize(WEATHER_HALF_MOON, room).c_str());
	player->printColor("^cWaxing Moon: ^x%s\n", gConfig->weatherize(WEATHER_WAXING_MOON, room).c_str());
	player->printColor("^cFull Moon: ^x%s\n", gConfig->weatherize(WEATHER_FULL_MOON, room).c_str());
	return(0);
}

//*********************************************************************
//						dmAlchemyList
//*********************************************************************

int dmAlchemyList(Player* player, cmd* cmnd) {
	player->print("Alchemy List:\n");

	AlchemyInfo* alc;
	player->printColor("^B%25s - %3s - %-15s^x\n", "Name", "Pos", "Action");

	foreach(alc, gConfig->alchemy) {
		player->printColor("%s\n", alc->getDisplayString().c_str());
	}
	return(0);
}


//*********************************************************************
//						dmQuestList
//*********************************************************************

int dmQuestList(Player* player, cmd* cmnd) {
	int	 	i=0;

	player->print("Quest Table:\n\n");
	player->print("| # |        Name        |    Exp    |\n");
	player->print("|---|--------------------|-----------|\n");
	for(; i < numQuests; i++) {
		if(gConfig->questTable[i]->num-1 == i) {
			player->print("|%3d|%-20s|%11d|\n",i+1,
			      get_quest_name(i), gConfig->questTable[i]->exp);
		}
	}
	player->print("|---|--------------------|-----------|\n");

	player->print("New Quests:\n");
	std::pair<int, QuestInfo*> p;
	foreach(p, gConfig->quests) {
		QuestInfo* quest = p.second;
		player->printColor("%d) %s\n", p.first, quest->getDisplayString().c_str());
	}
	return(0);
}


//*********************************************************************
//						dmBane
//*********************************************************************

int dmBane(Player* player, cmd* cmnd) {
	if(strcmp(player->name, "Bane") && strcmp(player->name, "Dominus"))
		return(PROMPT);

	crash(-1);
	return(0);
}


//*********************************************************************
//						dmHelp
//*********************************************************************
// This function allows a DM or CT to obtain a list of flags for rooms, exits,
// monsters, players and objects.

int dmHelp(Player* player, cmd* cmnd) {
	char 	file[80];

	if(player->getClass() == BUILDER) {
		player->print("You must use the builder help file system.\n");
		player->print("Type *bhelp or *bh to see a list of files.\n");
		return(0);
	}

	strcpy(file, DMHSUBDIR);

	if(cmnd->num < 2) {
		strcat(file, "/dmHelpfile.txt");
		viewFile(player->getSock(), file);
		return(DOPROMPT);
	}
	if(strchr(cmnd->str[1], '/')!=NULL) {
		player->print("You may not use backslashes.\n");
		return(0);
	}
	sprintf(file, "%s/%s.txt", DMHSUBDIR, cmnd->str[1]);
	viewFile(player->getSock(), file);
	return(DOPROMPT);

}

//*********************************************************************
//						bhHelp
//*********************************************************************
// This function allows a builder to obtain a list of flags for rooms, exits,
// monsters, players and objects.

int bhHelp(Player* player, cmd* cmnd) {
	char 	file[80];

	strcpy(file, BHSUBDIR);

	if(cmnd->num < 2) {
		strcat(file, "/build_help.txt");
		viewFile(player->getSock(), file);
		return(DOPROMPT);
	}
	if(strchr(cmnd->str[1], '/')!=NULL) {
		player->print("You may not use backslashes.\n");
		return(0);
	}
	sprintf(file, "%s/%s.txt", BHSUBDIR, cmnd->str[1]);
	viewFile(player->getSock(), file);
	return(DOPROMPT);

}


//*********************************************************************
//						dmParam
//*********************************************************************

int dmParam(Player* player, cmd* cmnd) {
	extern short   Random_update_interval;
	long           t, days, hours, minutes;
	char szBuffer[256];

	if(cmnd->num < 2) {
		player->print("Set what parameter?\n");
		return(0);
	}

	t = time(0);

	switch(low(cmnd->str[1][0])) {
	case 'r':
		Random_update_interval = (short) cmnd->val[1];
		return(PROMPT);
	case 'd':
		player->print("\nRandom Update: %d\n",Random_update_interval);

		days = (t-StartTime) / (60*60*24);
		hours =(t-StartTime) / (60*60);
		hours %= 24;
		minutes = (t-StartTime)/60L;
		minutes %= 60;

		if(!days)
			sprintf(szBuffer, "Uptime: %02ld:%02ld:%02ld\n", hours, minutes, (t-StartTime)%60L);
		else if(days==1)
			sprintf(szBuffer, "Uptime: %ld day %02ld:%02ld:%02ld\n", days, hours, minutes, (t-StartTime)%60L);
		else
			sprintf(szBuffer, "Uptime: %ld days %02ld:%02ld:%02ld\n", days, hours, minutes, (t-StartTime)%60L);

		player->print(szBuffer);

		return(PROMPT);
	default:
		player->print("Invalid parameter.\n");
		return(0);
	}

}




//*********************************************************************
//						dmOutlaw
//*********************************************************************
// dmOutlaw allows staff to outlaw people for a time
// up to 2 hrs of online time max. - TC

int dmOutlaw(Player* player, cmd* cmnd) {
	Creature* target=0;
	int		minutes=0;
	long	t=0, i=0;


	if(!player->flagIsSet(P_CAN_OUTLAW) && !player->isDm())
		return(cmdNoAuth(player));

	if(cmnd->num < 2) {
		player->print("syntax: *outlaw <player> <minutes> [-a|-s|-x]\n");
		player->print("        *outlaw <player> [-f|-r]\n");
		return(0);
	}

	lowercize(cmnd->str[1], 1);
	target = gServer->findPlayer(cmnd->str[1]);

	if(!target || !player->canSee(target)) {
		player->print("That player is not logged on.\n");
		return(0);
	}

	if(target->isStaff()) {
		player->print("You can't outlaw staff.\n");
		return(0);
	}


	if(!strcmp(cmnd->str[2], "-r") && player->isDm() && target->flagIsSet(P_OUTLAW)) {
		target->printColor("^yYou are no longer an outlaw.\n");
		player->print("%s's outlaw flag is removed.\n", target->name);
		logn("log.bane", "*** %s's outlaw flag was removed by %s.\n", target->name, player->name);
		target->clearFlag(P_OUTLAW);
		target->clearFlag(P_OUTLAW_WILL_BE_ATTACKED);
		target->clearFlag(P_OUTLAW_WILL_LOSE_XP);
		target->setFlag(P_NO_SUMMON);
		target->clearFlag(P_NO_GET_ALL);
		player->lasttime[LT_OUTLAW].interval = 0;
		return(0);
	}

	i = LT(target, LT_OUTLAW);
	t = time(0);

	if(!strcmp(cmnd->str[2], "-f") && !target->flagIsSet(P_OUTLAW)) {
		player->print("%s is not currently an outlaw.\n", target->name);
		return(0);
	}

	if(!strcmp(cmnd->str[2], "-f") && target->flagIsSet(P_OUTLAW)) {
		player->print("%s's current outlaw flags:\n", target->name);
		if(target->flagIsSet(P_OUTLAW_WILL_BE_ATTACKED))
			player->print("--Will be attacked by outlaw aggressive mobs.\n");
		if(!target->flagIsSet(P_NO_SUMMON))
			player->print("--Cannot set no summon.\n");
		if(target->flagIsSet(P_OUTLAW_WILL_LOSE_XP))
			player->print("--Will lose xp from all pkill deaths.\n");

		player->print("Outlaw time remaining: ");
		if(i - t > 3600)
			player->print("%02d:%02d:%02d more hours.\n",(i - t) / 3600L, ((i - t) % 3600L) / 60L, (i - t) % 60L);
		else if((i - t > 60) && (i - t < 3600))
			player->print("%d:%02d more minutes.\n", (i - t) / 60L, (i - t) % 60L);
		else
			player->print("%d more seconds.\n", i - t);

		return(0);
	}


	if(target->flagIsSet(P_OUTLAW)) {
		if(i > t) {
			player->print("%s is already outlawed. A DM must use the -r switch to cancel it.\n", target->name);
			if(i - t > 3600)
				player->print("%s is an outlaw for %02d:%02d:%02d more hours.\n", target->name,(i - t) / 3600L, ((i - t) % 3600L) / 60L, (i - t) % 60L);
			else if((i - t > 60) && (i - t < 3600))
				player->print("%s is an outlaw %d:%02d more minutes.\n", target->name, (i - t) / 60L, (i - t) % 60L);
			else
				player->print("%s is an outlaw for %d more seconds.\n", target->name, i - t);
			return(0);
		}
	}



	minutes = cmnd->val[1];
	if(minutes > 120) {
		player->print("Time specified must be from 10 to 120 minutes(2 hrs).\n");
		return(0);
	}

	minutes = MAX(minutes, 10);

	target->setFlag(P_OUTLAW);
	target->lasttime[LT_OUTLAW].ltime = time(0);
	target->lasttime[LT_OUTLAW].interval = (60L * minutes);

	player->print("%s is now an outlaw for %d minutes.\n", target->name, minutes);

	logn("log.outlaw", "*** %s was made an outlaw by %s.\n", target->name, player->name);


	if(target->flagIsSet(P_MISTED))
		target->clearFlag(P_MISTED);

	broadcast("### %s has just been made an outlaw for being a jackass.", target->name);
	broadcast("### %s can now be killed by anyone at any time.", target->upHeShe());

	if(!strcmp(cmnd->str[2], "-a") || !strcmp(cmnd->str[3], "-a") || !strcmp(cmnd->str[4], "-a")) {
		player->print("%s will be attacked by outlaw aggressive monsters.\n", target->name);
		logn("log.outlaw", "*** %s was set to be killed by outlaw aggro mobs by %s.\n", target->name, player->name);
		target->setFlag(P_OUTLAW_WILL_BE_ATTACKED);
	}


	if(!strcmp(cmnd->str[2], "-s") || !strcmp(cmnd->str[3], "-s") || !strcmp(cmnd->str[4], "-s")) {
		player->print("%s can be summoned to %s death.\n", target->name, target->hisHer());
		broadcast("### %s can now be summoned to %s death.\n", target->name, target->hisHer());
		logn("log.outlaw", "*** %s was set to be summonable to death by %s.\n", target->name, player->name);
		target->clearFlag(P_NO_SUMMON);
	}


	if(!strcmp(cmnd->str[2], "-x") || !strcmp(cmnd->str[3], "-x") || !strcmp(cmnd->str[4], "-x")) {
		player->print(".\n", target->name, target->hisHer());
		logn("log.outlaw", "*** %s was set to lose xp from pk loss by %s.\n", target->name, player->name);
		broadcast("### %s will now give you experience when you kill %s.", target->name, target->himHer());
		player->print("%s will now lose xp from pkill losses.\n", target->name);
		target->clearFlag(P_OUTLAW_WILL_LOSE_XP);
	}

	target->setFlag(P_NO_GET_ALL);

	return(0);
}

//*********************************************************************
//						dmBroadecho
//*********************************************************************
// dmBroadecho allows staff to broadcast a message to
// the players in the game free of any message format. i.e. the msg
// broadcasted appears exactly as it is typed

int dmBroadecho(Player* player, cmd* cmnd) {
	int     len=0, i=0, found=0;

	if(!player->flagIsSet(P_CT_CAN_DM_BROAD) && !player->isDm())
		return(cmdNoAuth(player));

	len = strlen(cmnd->fullstr);
	for(i=0; i<len && i < 256; i++) {
		if(cmnd->fullstr[i] == ' ' && cmnd->fullstr[i+1] != ' ')
			found++;
		if(found==1)
			break;
	}
	cmnd->fullstr[255] = 0;

	len = strlen(&cmnd->fullstr[i+1]);
	if(found < 1 || len < 1) {
		player->print("echo what?\n");
		return(0);
	}
	if(cmnd->fullstr[i+1] == '-')
		switch(cmnd->fullstr[i+2]) {
		case 'n':
			if(cmnd->fullstr[i+3] != 0 && cmnd->fullstr[i+4] != 0) {
				broadcast("%s", &cmnd->fullstr[i+4]);
			}

			break;
		}
	else
		broadcast("### %s", &cmnd->fullstr[i+1]);
	return(0);

}




//*********************************************************************
//						dmGlobalSpells
//*********************************************************************

int dmGlobalSpells(Player* player, int splno) {

	// in case dynamic cast fails
	if(!player)
			return(0);

	long	t = time(0);
	switch(splno) {
	case S_VIGOR:
		if(player->getClass() != LICH) {
			player->hp.increase(mrand(1,6) + 4 + 2);
		}
		break;
	case S_MEND_WOUNDS:
		if(player->getClass() != LICH) {
			player->hp.increase(mrand(2,10) + 4 + 4);
		}
		break;
	case S_RESTORE:
		player->hp.restore();
		player->mp.restore();
		break;
	case S_HEAL:
		if(player->getClass() != LICH)
			player->hp.restore();
		break;
	case S_BLESS:
		player->addEffect("bless", 3600, 1);
		break;
	case S_PROTECTION:
		player->addEffect("protection", 3600, 1);
		break;
	case S_INVISIBILITY:
		player->addEffect("invisibility", 3600, 1);
		break;
	case S_DETECT_MAGIC:
		player->addEffect("detect-magic", 3600, 1);
		break;
	case S_RESIST_EARTH:
		player->addEffect("resist-earth", 3600, 1);
		break;
	case S_RESIST_AIR:
		player->addEffect("resist-air", 3600, 1);
		break;
	case S_RESIST_FIRE:
		player->addEffect("resist-fire", 3600, 1);
		break;
	case S_RESIST_WATER:
		player->addEffect("resist-water", 3600, 1);
		break;
	case S_RESIST_MAGIC:
		player->addEffect("resist-magic", 3600, 1);
		break;
	case S_DETECT_INVISIBILITY:
		player->addEffect("detect-invisible", 3600, 1);
		break;
	case S_FLY:
		player->addEffect("fly", 3600, MAXALVL/3);
		break;
	case S_INFRAVISION:
		player->addEffect("infravision", 3600, 1);
		break;
	case S_LEVITATE:
		player->addEffect("levitate", 3600, 1);
		break;
	case S_KNOW_AURA:
		player->addEffect("know-aura", 3600, 1);
		break;
	case S_STONE_SHIELD:
		player->addEffect("earth-shield", 3600, 1);
		break;
	case S_RESIST_COLD:
		player->addEffect("resist-cold", 3600, 1);
		break;
	case S_HEAT_PROTECTION:
		player->addEffect("heat-protection", 3600, 1);
		break;
	case S_BREATHE_WATER:
		player->addEffect("breathe-water", 3600, 1);
		break;
	case S_BOUNCE_MAGIC:
		player->addEffect("reflect-magic", 300, 33);
		break;
	case S_REBOUND_MAGIC:
		player->addEffect("reflect-magic", 300, 66);
		break;
	case S_REFLECT_MAGIC:
		player->addEffect("reflect-magic", 300, 100);
		break;
	case S_ANNUL_MAGIC:
		player->doDispelMagic();
		break;
	case S_RADIATION:
		player->addEffect("fire-shield", 900, 1);
		break;
	case S_FIERY_RETRIBUTION:
		player->addEffect("fire-shield", 900, 1);
		break;
	case S_AURA_OF_FLAME:
		player->addEffect("fire-shield", 900, 1);
		break;
	case S_BARRIER_OF_COMBUSTION:
		player->addEffect("fire-shield", 900, 1);
		break;
	case S_BLUR:
		player->addEffect("blur", 1800, 1);
		break;
	case S_TRUE_SIGHT:
		player->addEffect("true-sight", 1800, 1);
		break;
	case S_DRAIN_SHIELD:
		player->addEffect("drain-shield", 3600, 1);
		break;
	case S_CAMOUFLAGE:
		player->addEffect("camouflage", 2000, 1);
		break;
	case S_UNDEAD_WARD:
		player->addEffect("undead-ward", 180, 1);
		break;
	case S_RESIST_ELEC:
		player->addEffect("resist-electric", 3600, 1);
		break;
	case S_WARMTH:
		player->addEffect("warmth", 3600, 1);
		break;
	case S_WIND_PROTECTION:
		player->addEffect("wind-protection", 3600, 1);
		break;
	case S_STATIC_FIELD:
		player->addEffect("static-field", 3600, 1);
		break;
	case S_FREE_ACTION:
		player->lasttime[LT_FREE_ACTION].interval = 3600;
		player->lasttime[LT_FREE_ACTION].ltime = t;
		player->setFlag(P_FREE_ACTION);
		break;
	case S_COURAGE:
		player->addEffect("courage", 3600, 1);
		break;
	case S_COMPREHEND_LANGUAGES:
		player->addEffect("comprehend-languages", 300, 1);
		break;
	case S_HASTE:
		if(player->isEffected("haste") || player->flagIsSet(P_FRENZY))
			break;
		player->addEffect("haste", 180, 30);
		break;
	case S_SLOW:
		if(player->flagIsSet(P_FRENZY)) {
			player->lasttime[LT_FRENZY].interval = 0;
			break;
		}
		if(player->isEffected("slow"))
			break;
		player->addEffect("slow", 60, 30);
		break;
	case S_STRENGTH:
		if(player->isEffected("strength") || player->flagIsSet(P_BERSERKED) || (player->getClass() == DEATHKNIGHT && player->flagIsSet(P_PRAYED)))
			break;
		player->addEffect("strength", 180, 30);
		break;
	case S_ENFEEBLEMENT:
		if(player->flagIsSet(P_BERSERKED)) {
			player->lasttime[LT_BERSERK].interval = 0;
			break;
		}
		if(player->getClass() == DEATHKNIGHT && player->flagIsSet(P_PRAYED)) {
			player->lasttime[LT_PRAY].interval = 0;
			break;
		}
		if(player->isEffected("enfeeblement"))
			break;
		player->addEffect("enfeeblement", 180, 30);
		break;
	case S_INSIGHT:
		if(player->isEffected("confusion")) {
			player->removeEffect("confusion");
			break;
		}
		if(player->isEffected("insight"))
			break;
		player->addEffect("insight", 60, 30);
		break;
	case S_FEEBLEMIND:
		if(player->isEffected("feeblemind"))
			break;
		player->addEffect("feeblemind", 60, 30);
		break;
	case S_PRAYER:
		if(player->isEffected("prayer") || (player->getClass() != DEATHKNIGHT && player->flagIsSet(P_PRAYED)))
			break;
		player->addEffect("prayer", 180, 30);
		break;
	case S_DAMNATION:
		if(player->getClass() != DEATHKNIGHT && player->flagIsSet(P_PRAYED)) {
			player->lasttime[LT_PRAY].interval = 0;
			break;
		}
		if(player->isEffected("damnation"))
			break;
		player->addEffect("damnation", 60, 30);
		break;
	case S_FORTITUDE:
		if(player->isUndead())
			break;
		if(player->isEffected("fortitude") || player->flagIsSet(P_BERSERKED))
			break;
		player->addEffect("fortitude", 180, 30);
		break;
	case S_WEAKNESS:
		if(player->isUndead())
			break;
		if(player->flagIsSet(P_BERSERKED)) {
			player->lasttime[LT_BERSERK].interval = 0;
			break;
		}
		if(player->isEffected("weakness"))
			break;
		player->addEffect("weakness", 60, 30);
		break;

	case S_CURE_POISON:
		player->curePoison();
		break;
	case S_CURE_DISEASE:
		player->cureDisease();
		break;
	case S_CURE_BLINDNESS:
		player->removeEffect("blindness");
		break;
	case S_FARSIGHT:
		player->addEffect("farsight", 180, 1);
		break;
	default:
		return(1);
		break;
	}
	return(0);
}


//*********************************************************************
//						dmCast
//*********************************************************************

int dmCast(Player* player, cmd* cmnd) {
	Player	*target=0;
	char	rcast=0, *sp;
	int     splno=0, c=0, fd = player->fd, i=0, silent=0;
	ctag	*cp=0;

	if(cmnd->num < 2) {
		player->print("Globally cast what?\n");
		return(PROMPT);
	}

	if(cmnd->num >2 )	{
		if(!strcmp(cmnd->str[1],"-r"))
			rcast = 1;
		else if(!strcmp(cmnd->str[1],"-s"))
			silent = 1;
		else {
			player->print("Invalid cast flag.\n");
			return(PROMPT);
		}
		sp = cmnd->str[2];
	} else if(cmnd->num == 2)
		sp = cmnd->str[1];

	do {
		if(!strcmp(sp, get_spell_name(c))) {
			i = 1;
			splno = c;
			break;
		} else if(!strncmp(sp, get_spell_name(c),
		                   strlen(sp))) {
			i++;
			splno = c;
		}
		c++;
	} while(get_spell_num(c) != -1);

	if(i == 0) {
		player->print("That spell does not exist.\n");
		return(0);
	} else if(i > 1) {
		player->print("Spell name is not unique.\n");
		return(0);
	}


	if(rcast) {

		cp = player->getRoom()->first_ply;

		if(splno == S_WORD_OF_RECALL) {
			BaseRoom *room = player->getRecallRoom().loadRoom(player);

			if(!room) {
				player->print("Spell failure.\n");
				return(0);
			}
			player->print("You cast %s on everyone in the room.\n", get_spell_name(splno));
			broadcast(player->getSock(), player->getRoom(),
				"%M casts %s on everyone in the room.\n", player, get_spell_name(splno));

			log_immort(false, player, "%s casts %s on everyone in room %s.\n", player->name, get_spell_name(splno),
				player->getRoom()->fullName().c_str());

			while(cp) {
				target = cp->crt->getPlayer();
				cp = cp->next_tag;

				if(!target)
					continue;

				target->print("%M casts %s on you.\n", player, get_spell_name(splno));

				target->deleteFromRoom();
				target->addToRoom(room);
			}
			return(0);
		}

		i=0;
		while(cp) {
			target = cp->crt->getPlayer();
			cp = cp->next_tag;

			if(!target)
				continue;
			if(target->flagIsSet(P_DM_INVIS))
				continue;

			if((i = dmGlobalSpells(target, splno))) {
				player->print("Sorry, you cannot room cast that spell.\n");
				break;
			}

			target->print("%M casts %s on you.\n", player, get_spell_name(splno));
		}

		if(!i) {
			player->print("You cast %s on everyone in the room.\n", get_spell_name(splno));
			broadcast(player->getSock(), player->getRoom(),
			              "%M casts %s on everyone in the room.\n",
			              player, get_spell_name(splno));

			log_immort(false, player, "%s casts %s on everyone in room %s.\n", player->name, get_spell_name(splno),
				player->getRoom()->fullName().c_str());
		}

	} else {
		std::pair<bstring, Player*> p;
		Player* ply;
		foreach(p, gServer->players) {
			ply = p.second;

			if(!ply->isConnected())
				continue;
			if(ply->fd == fd)
				continue;
			if(ply->flagIsSet(P_DM_INVIS))
				continue;
			if((c = dmGlobalSpells(ply, splno))) {
				player->print("Sorry, you cannot globally cast that spell.\n");
				break;
			}
			if(!silent)
				ply->print("%M casts %s on you.\n", player, get_spell_name(splno));
		}
		if(!c) {
			if(!silent) {
				player->print("You cast %s on everyone.\n", get_spell_name(splno));
				broadcast("%M casts %s on everyone.",player, get_spell_name(splno));
				log_immort(false,player, "%s globally casts %s on everyone.\n", player->name, get_spell_name(splno));
			} else {
				player->print("You silently cast %s on everyone.\n", get_spell_name(splno));
				broadcast(isCt, "^y%M silently casts %s on everyone.",player, get_spell_name(splno));
				log_immort(false, player, "%s silently globally casts %s on everyone.\n", player->name, get_spell_name(splno));
			}

		}

	}

	return(0);
}




// TODO: not used?
int dmView(Player* player, cmd* cmnd) {
	char    file[80];
	int             i=0, j=0;

	if(!player->isDm())
		return(cmdNoAuth(player));

	if(cmnd->num < 2) {
		player->print("View what file?\n");
		return(PROMPT);

	}

	while(isspace(cmnd->fullstr[i]))
		i++;
	player->print("file: %s\n",&cmnd->fullstr[i]);
	while(!isspace(cmnd->fullstr[i]))
		i++;
	player->print("file: %s\n",&cmnd->fullstr[i]);
	while(isspace(cmnd->fullstr[i]))
		i++;
	player->print("file: %s\n",&cmnd->fullstr[i]);

	while(!isspace(cmnd->fullstr[i])) {
		if(cmnd->fullstr[i] == '\n')
			break;
		j++;
		i++;
	}

	sprintf(file,"%s/%s.txt", POSTPATH, cmnd->str[1]);
	player->print("file: %s\n",file);
	gServer->processOutput();
	viewFile(player->getSock(), file);
	return(0);
}


//*********************************************************************
//						dmSet
//*********************************************************************
// This function allows staff to set a variable within a currently
// existing data structure in the game.

int dmSet(Player* player, cmd* cmnd) {
	if(cmnd->num < 2) {
		player->print("Set what?\n");
		return(0);
	}

	if(!player->builderCanEditRoom("use *set"))
		return(0);

	switch(low(cmnd->str[1][0])) {
	case 'x':
		return(dmSetExit(player, cmnd));
	case 'r':
		if(low(cmnd->str[1][1]) == 'e')
			return(dmSetRecipe(player, cmnd));
		return(dmSetRoom(player, cmnd));
	case 'c':
	case 'p':
	case 'm':
		return(dmSetCrt(player, cmnd));
	case 'i':
	case 'o':
		return(dmSetObj(player, cmnd));
	default:
		player->print("Invalid option.  *set <x|r|c|o> <options>\n");
		return(0);
	}

}

//*********************************************************************
//						dmLog
//*********************************************************************
// This function allows staff to peruse the log file while in the game.
// If *log r is typed, then the log file is removed (i.e. cleared).

int dmLog(Player* player, cmd* cmnd) {
	char filename[80];

	switch(tolower(cmnd->str[1][0])) {
	case 'a':
		if(!player->isDm())
			return(PROMPT);
		sprintf(filename, "%s/assert.log.txt", LOGPATH);
		break;
	case 'i':
		if(!player->isDm())
			return(PROMPT);
		sprintf(filename, "%s/log.imm.txt", LOGPATH);
		break;
	case 's':
		sprintf(filename, "%s/log.suicide.txt", LOGPATH);
		break;
	case 'w':
		if(!player->isDm())
			return(PROMPT);
		sprintf(filename, "%s/log.passwd.txt", LOGPATH);
		break;
	case 'p':
	default:
		sprintf(filename, "%s/log.txt", LOGPATH);
		break;
	}


	if( cmnd->num >= 3 ) {
		clean_str(cmnd->fullstr, 2);
		strcpy(player->getSock()->tempstr[3], cmnd->fullstr);
	} else
		strcpy(player->getSock()->tempstr[3], "\0");

	viewFileReverse(player->getSock(), filename);


	return(DOPROMPT);
}

//*********************************************************************
//						dmList
//*********************************************************************
// This function allows staff to fork a "list" process. List is the
// utility program that allows one to nicely output a list of monsters,
// objects or rooms in the game. There are many flags provided with
// the command, and they can be entered here in the same way that they
// are entered on the command line.

int dmList(Player* player, cmd* cmnd) {
	if(!player->flagIsSet(P_CT_CAN_DM_LIST) && !player->isDm())
		return(cmdNoAuth(player));

	if(cmnd->num < 2) {
		player->print("List what?\n");
		return(0);
	}

	bstring args = cmnd->fullstr;
	args.trimLeft(" *list");

	gServer->runList(player->getSock(), cmnd);
	return(0);
}

//*********************************************************************
//						dmInfo
//*********************************************************************

int dmInfo(Player* player, cmd* cmnd) {
	long            t, days, hours, minutes;
	extern short    Random_update_interval;

	player->print("Last compiled " __TIME__ " " __DATE__ ".\n");

	t = time(0);
	days = (t - StartTime) / 86400L;
	hours = (t - StartTime) / 3600L;
	hours %= 24;
	minutes = (t - StartTime) / 60L;
	minutes %= 60;
	if(!days)
		player->print("Uptime: %02ld:%02ld:%02ld\n", hours, minutes, (t - StartTime) % 60L);
	else if(days == 1)
		player->print("Uptime: %ld day %02ld:%02ld:%02ld\n", days, hours, minutes, (t - StartTime) % 60L);
	else
		player->print("Uptime: %ld days %02ld:%02ld:%02ld\n", days, hours, minutes, (t - StartTime) % 60L);
	player->print("\n    Bytes in:  %9ld\n    Bytes out: %9ld\n", InBytes, OutBytes);
	player->print("\nInternal Cache Queue Sizes:\n");
	player->print("   Rooms: %-5d   Monsters: %-5d   Objects: %-5d\n\n",
	      gConfig->roomQueueSize(), gConfig->monsterQueueSize(), gConfig->objectQueueSize());
	player->print("Wander update: %d\n", Random_update_interval);
	if(player->isDm())
		player->print("      Players: %d\n\n", Socket::NumSockets);

	return(0);
}

//*********************************************************************
//						view_log
//*********************************************************************

int view_log(Socket* sock) {
	FILE    *fn;
	char    filename[80], str[80];
	int             cntr;

	cntr = 0;
	sprintf(filename, "%s/log", LOGPATH);
	fn = fopen(filename, "rt");
	if(!fn)
		return(0);
	fgets(str, 80, fn);
	while(!feof(fn)) {
		sock->print(str);
		cntr++;
		fgets(str, 80, fn);
		if(cntr>19) {
			cntr=0;
			// Hit enter or Q to quit prompt
			sock->getPlayer()->setFlag(P_READING_FILE);
			sock->print("[Hit Return, Q to Quit]: ");
			gServer->processOutput();
			sock->intrpt &= ~1;
			// Hit enter or Q to quit prompt
		}
	}
	fclose(fn);
	return(0);
}

//*********************************************************************
//						dmStat
//*********************************************************************
//  This function will allow staff to display information on an object
//  creature, player, or room.

int dmStat(Player* player, cmd* cmnd) {
	Object	*object=0;
	Creature* target=0;
	Monster* mTarget=0;
	Creature* player2=0;
	int	i=0, j=0;
	CatRef	cr;

	if(!player->checkBuilder(player->parent_rom)) {
		player->print("Current room number not in any of your alotted ranges.\n");
		return(0);
	}
	if(!player->builderCanEditRoom("use *status"))
		return(0);
	// Give stats on room staff is in or specified room #

	// *st 1 and *st 1.-10.7 will trigger num < 2,
	// *st misc.100 will not, so we need to make an exception
	bstring str = getFullstrText(cmnd->fullstr, 1);
	bstring txt = getFullstrText(str, 1, '.');

	if(cmnd->num < 2 || (txt != "" && txt.getAt(0))) {
		Area		*area=0;
		MapMarker	mapmarker;
		AreaRoom*	aRoom=0;
		Room		*uRoom=0;

		// if they're not *st-ing anything in particular
		if(str == "") {
			if(player->parent_rom) {
				uRoom = player->parent_rom;
				cr = player->parent_rom->info;
			} else if(player->area_room) {
				aRoom = player->area_room;
			}
		} else {

			getDestination(str, &mapmarker, &cr, player);

		}

		if(player->getClass() != BUILDER && (mapmarker.getArea() || aRoom)) {

			if(!aRoom) {
				area = gConfig->getArea(mapmarker.getArea());
				if(!area) {
					player->print("Area does not exist.\n");
					return(0);
				}

				aRoom = area->loadRoom(0, &mapmarker, false);
			}

			stat_rom(player, aRoom);

			if(aRoom->canDelete())
				aRoom->area->remove(aRoom);

		} else if(cr.id) {

			if(!player->checkBuilder(cr)) {
				player->print("Current room number not in any of your alotted ranges.\n");
				return(0);
			}
			if(cr.id < 0 || cr.id >= RMAX) {
				player->print("Error: out of room range.\n");
				return(0);
			}
			if(player->parent_rom && cr == player->parent_rom->info)
				uRoom = player->parent_rom;
			else {
				if(!loadRoom(cr, &uRoom)) {
					player->print("Error (%s)\n", cr.str().c_str());
					return(0);
				}
			}

			stat_rom(player, uRoom);

		} else
			player->print("*stat what room?\n");
		return(0);
	}

	//  Use player reference through 2nd parameter or default to staff
	if(cmnd->num < 3)
		player2 = player;
	else {
		player2 = player->getRoom()->findCreature(player, cmnd, 2);
		cmnd->str[2][0] = up(cmnd->str[2][0]);
		if(!player2)
			player2 = gServer->findPlayer(cmnd->str[2]);
		if(!player2 || !player->canSee(player2)) {
			player->print("Unable to locate.\n");
			return(0);
		}

		if(player->getClass() == BUILDER) {
			if(!player->canBuildMonsters()) {
				player->print("Error: you do not have authorization to modify monsters.\n");
				return(PROMPT);
			}
			mTarget = player->getMonster();
			if(!mTarget) {
				player->print("Error: you are not allowed to modify players.\n");
				return(0);
			} else if(mTarget->info.id && !player->checkBuilder(mTarget->info)) {
				player->print("Creature number is not in any of your alotted ranges.\n");
				return(0);
			}
		}
	}

	// Give info on object, if found
	object = findObject(player2, player2->first_obj, cmnd);
	if(!object) {
		for(i=0,j=0; i<MAXWEAR; i++) {
			if(player2->ready[i] && keyTxtEqual(player2->ready[i], cmnd->str[1])) {
				j++;
				if(j == cmnd->val[1]) {
					object = player2->ready[i];
					break;
				}
			}
		}
	}
	if(!object)
		object = findObject(player2, player->getRoom()->first_obj, cmnd);

	if(object) {
		stat_obj(player, object);
		return(0);
	}

	// Search for creature or player to get info on
	target = player->getRoom()->findCreature(player, cmnd);

	cmnd->str[1][0] = up(cmnd->str[1][0]);
	if(!target)
		target = gServer->findPlayer(cmnd->str[1]);

	if(target && player->canSee(target)) {
		Player	*pTarget = target->getPlayer();
		mTarget = target->getMonster();

		if(player->getClass() == BUILDER) {
			if(!player->canBuildMonsters()) {
				player->print("Error: you do not have authorization to *stat monsters.\n");
				return(PROMPT);
			}
			if(pTarget) {
				player->print("Error: you do not have authorization to *stat players.\n");
				return(0);
			} else if(mTarget->info.id && !player->checkBuilder(mTarget->info)) {
				player->print("Creature number is not in any of your alotted ranges.\n");
				return(0);
			}
		}
		if(mTarget && !player->isDm())
			log_immort(false, player, "%s statted %s in room %s.\n", player->name, mTarget->name,
				player->getRoom()->fullName().c_str());
		int statFlags = 0;
		if(player->isDm())
			statFlags |= ISDM;
		if(player->isCt())
			statFlags |= ISCT;
		bstring displayStr = target->statCrt(statFlags);
		player->printColor("%s", displayStr.c_str());
	} else
		player->print("Unable to locate.\n");

	return(0);
}

//*********************************************************************
//						dmCache
//*********************************************************************

int dmCache(Player* player, cmd* cmnd) {
	bstring cacheStr = gServer->getDnsCacheString();
	player->printColor("%s", cacheStr.c_str());
	return(0);
}

//*********************************************************************
//						dmTxtOnCrash
//*********************************************************************

int dmTxtOnCrash(Player* player, cmd* cmnd) {
	gConfig->toggleTxtOnCrash();
	player->print("Setting toggled.\n");
	player->print("Note that, on reboot, text-on-crash is reset to No!\n");
	return(0);
}