1stMUD4.0/bin/
1stMUD4.0/doc/MPDocs/
1stMUD4.0/player/
1stMUD4.0/win32/
1stMUD4.0/win32/rom/
diff -ur -x config -x o -x rom src/Makefile new/Makefile
--- src/Makefile	Tue May 27 02:45:45 2003
+++ new/Makefile	Sun Aug 31 19:23:21 2003
@@ -1,41 +1,11 @@
-CC      = g++
-PROF    = -ggdb3
-WARN    = -Wall -Werror
-LIBS	= -lcrypt -lz
-#STRHASH: 0 = no string hashing.
-#         1 = ROM fread_string() hashing only.
-#         2 = full string hashing
-D_FLAGS = -DSTRHASH=0 #-DNO_MCCP -DNO_WEB -DNOCRYPT
-C_FLAGS = $(WARN) $(PROF) $(D_FLAGS)
-L_FLAGS = $(PROF) $(LIBS)
+beginhelp:
+	@echo =============================================================================
+	@echo Change into the config directory and run ./configure to create a makefile
+	@echo
+	@echo Notes: The makefile configure generates requires a version of make that
+	@echo "       has the sort function amoung other things."
+	@echo
+	@echo "       On the FreeBSD and OpenBSD platforms you will most likely need to"
+	@echo "       use gmake to compile the code."
+	@echo =============================================================================
 
-C_FILES := $(wildcard *.c)
-O_FILES := $(patsubst %.c, %.o, $(C_FILES))
-H_FILES := $(wildcard *.h)
-
-all: rom
-
-rom: $(O_FILES)
-	@rm -f rom
-	@$(CC) $(L_FLAGS) -o rom $(O_FILES)
-	@echo "Done."
-
-.c.o: merc.h
-	@echo "`date +"%X"` : Compiling $<..."
-	@$(CC) -c $(C_FLAGS) $<
-
-clean:
-	@rm -rf *.o *~ *.orig *.rej \#* *core*
-	@echo "Done cleaning."
-
-indent:
-	@indent $(C_FILES) $(H_FILES)
-	@echo "Done formating files."
-
-depend:
-	@$(CC) -E -MM $(C_FLAGS) $(C_FILES) -I. > .depend
-	@echo "Done making depend file."
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-include .depend
diff -ur -x config -x o -x rom src/act_comm.c new/act_comm.c
--- src/act_comm.c	Tue May 27 02:46:35 2003
+++ new/act_comm.c	Sun Aug 31 19:23:20 2003
@@ -22,28 +22,17 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <unistd.h>
-#include <sys/time.h>
-#else
-#include "../win32/winstuff.h"
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <stdarg.h>
 #include "merc.h"
 #include "interp.h"
 #include "recycle.h"
 #include "tables.h"
 #include "lookup.h"
 #include "olc.h"
+#include "gcn.h"
 
 /* RT code to delete yourself */
 
@@ -57,14 +46,14 @@
 	char strsave[MAX_INPUT_LENGTH];
 	int hash;
 	ROOM_INDEX_DATA *pRoom;
-	void update_webpasses(CHAR_DATA * ch, bool pDelete);
+	PROTOTYPE(void update_webpasses, (CHAR_DATA *, bool));
 
 	if (IS_NPC(ch))
 		return;
 
 	if (ch->pcdata->confirm_delete)
 	{
-		if (argument[0] != '\0')
+		if (!IS_NULLSTR(argument))
 		{
 			chprintln(ch, "Delete status removed.");
 			ch->pcdata->confirm_delete = FALSE;
@@ -100,7 +89,7 @@
 		}
 	}
 
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Just type delete. No argument.");
 		return;
@@ -113,304 +102,6 @@
 	wiznet("$N is contemplating deletion.", ch, NULL, 0, 0, get_trust(ch));
 }
 
-void update_last_data(CHAR_DATA * sender, CHAR_DATA * viewer, int last,
-					  const char *chan, const char *str, int type)
-{
-	int i;
-	char *time;
-	char buf[MSL];
-
-	if (IS_NPC(viewer) || IS_NULLSTR(str) || IS_NULLSTR(chan) || last < 0
-		|| last >= LAST_MAX)
-		return;
-
-	for (i = LAST_PAGE_LENGTH - 1; i > 0; i--)
-	{
-		replace_string(viewer->pcdata->history[last][i],
-					   viewer->pcdata->history[last][i - 1]);
-	}
-
-	time = str_time(current_time, GET_TZONE(viewer), "%r");
-	switch (type)
-	{
-	case CHANNEL_NORMAL:
-		sprintf(buf, "[%s] %s{x %s says '%s'{x", time, chan, PERS(sender,
-																  viewer), str);
-		replace_string(viewer->pcdata->history[last][0], buf);
-		break;
-	case CHANNEL_SOCIAL:
-		sprintf(buf, "[%s] %s{x %s{x", time, chan, str);
-		replace_string(viewer->pcdata->history[last][0], buf);
-		break;
-	case CHANNEL_EMOTE:
-		sprintf(buf, "[%s] %s{x %s %s{x",
-				time, chan, PERS(sender, viewer), str);
-		replace_string(viewer->pcdata->history[last][0], buf);
-		break;
-	default:
-		bugf("bad channel type [%d]", type);
-		break;
-	}
-}
-
-void view_last_data(CHAR_DATA * ch, int last)
-{
-	int i;
-	bool found = FALSE;
-
-	if (last < 0 || last >= LAST_MAX)
-		return;
-
-	for (i = LAST_PAGE_LENGTH - 1; i >= 0; i--)
-	{
-		if (!IS_NULLSTR(ch->pcdata->history[last][i]))
-		{
-			found = TRUE;
-			chprintln(ch, ch->pcdata->history[last][i]);
-		}
-	}
-	if (!found)
-		chprintln(ch, "None.");
-}
-
-bool display_channel(CHAR_DATA * ch, CHAR_DATA * victim,
-					 enum special_flags spec_flag)
-{
-	if (!ch || !victim)
-		return FALSE;
-
-	if (IS_SET(victim->comm, COMM_QUIET))
-		return FALSE;
-
-	switch (spec_flag)
-	{
-	case spec_clan_flag:
-		if (!is_same_clan(ch, victim))
-			return FALSE;
-		break;
-	case spec_imm_flag:
-		if (!IS_IMMORTAL(victim))
-			return FALSE;
-		break;
-	case spec_buddy_flag:
-		if (victim != ch
-			&& (check_buddy(ch, victim) == -1 || check_buddy(victim, ch) == -1))
-			return FALSE;
-		break;
-	case spec_public_flag:
-		return TRUE;
-		break;
-	}
-
-	return TRUE;
-}
-
-void channel_social(CHAR_DATA * ch, CHAR_DATA * victim,
-					flag_t bit, const char *string, const char *type,
-					enum special_flags spec_flag, int last_type)
-{
-	DESCRIPTOR_DATA *d;
-
-	for (d = descriptor_first; d; d = d->next)
-	{
-		CHAR_DATA *vch = CH(d);
-
-		if (d->connected != CON_PLAYING)
-			continue;
-
-		if (vch && (vch != ch) && (vch != victim)
-			&& display_channel(ch, vch, spec_flag)
-			&& (!bit || !IS_SET(vch->comm, bit))
-			&& !IS_SET(vch->comm, COMM_NOGOCIAL))
-		{
-			char buf[MSL];
-
-			sprintf(buf, "%s %s", type, string);
-			perform_act(buf, ch, NULL, victim, 0, vch);
-			update_last_data(ch, vch, last_type, type,
-							 perform_act_string(string, ch, NULL, victim,
-												FALSE), CHANNEL_SOCIAL);
-		}
-	}
-	update_last_data(ch, ch, last_type, type,
-					 perform_act_string(string, ch, NULL, victim, FALSE),
-					 CHANNEL_SOCIAL);
-}
-
-void public_ch(CHAR_DATA * ch, const char *argument,
-			   const char *type, flag_t bitname, enum special_flags spec_flag,
-			   int last_type)
-{
-	char command[MIL + 100];
-	DESCRIPTOR_DATA *d;
-	bool display_wholist = FALSE, fEmote = FALSE;
-	char arg_left[MSL];
-
-	if (IS_NULLSTR(argument))
-	{
-		if (!bitname)
-			chprintln(ch, "What do you want to say?");
-		else
-		{
-			set_on_off(ch, &ch->comm, bitname,
-					   FORMATF("%s channel is now OFF.{x", type),
-					   FORMATF("%s channel is now ON.{x", type));
-		}
-	}
-	else
-	{
-		if (IS_SET(ch->comm, COMM_QUIET))
-		{
-			chprintln(ch, "You must turn off quiet mode first.");
-			return;
-		}
-		if (IS_SET(ch->comm, COMM_NOCHANNELS))
-		{
-			chprintln(ch, "The gods have revoked your channel priviliges.");
-			return;
-		}
-		if (bitname)
-			REMOVE_BIT(ch->comm, (bitname));
-
-		strcpy(arg_left, argument);
-
-		argument = one_argument(argument, command);
-		if (!str_cmp(command, "+"))
-		{
-			CHAR_DATA *victim;
-			char buf[MIL + 200];
-			SOCIAL_DATA *cmd;
-			char argx[MIL];
-
-			argument = one_argument(argument, command);
-			if (IS_NULLSTR(command))
-			{
-				chprintln
-					(ch,
-					 "{W<Channel> + <social> is used for channel based socials.{x");
-				return;
-			}
-			if (!(cmd = find_social(command)))
-			{
-				chprintln(ch, "{WWhat kind of social is that?!?!{x");
-				return;
-			}
-			one_argument(argument, argx);
-			victim = NULL;
-			if (IS_NULLSTR(argx))
-			{
-				sprintf(buf, "%s %s", type, cmd->char_no_arg);
-				act_new(buf, ch, NULL, NULL, TO_CHAR, POS_DEAD);
-				channel_social(ch, NULL, bitname,
-							   cmd->others_no_arg, type, spec_flag, last_type);
-			}
-			else if ((victim = get_char_world(ch, argx)) == NULL)
-			{
-				chprintln(ch, "They aren't here.");
-				return;
-			}
-			else
-			{
-				if (!display_channel(ch, victim, spec_flag))
-				{
-					chprintln(ch, "They can't use that channel.");
-					return;
-				}
-				if (victim == ch)
-				{
-					sprintf(buf, "%s %s", type, cmd->char_auto);
-					act_new(buf, ch, NULL, NULL, TO_CHAR, POS_DEAD);
-					channel_social(ch, victim, bitname,
-								   cmd->others_auto, type,
-								   spec_flag, last_type);
-				}
-				else
-				{
-					sprintf(buf, "%s %s", type, cmd->char_found);
-					act_new(buf, ch, NULL, victim, TO_CHAR, POS_DEAD);
-					if ((!bitname || !IS_SET(victim->comm, bitname))
-						&& !IS_SET(victim->comm, COMM_NOGOCIAL)
-						&& display_channel(ch, victim, spec_flag))
-					{
-						sprintf(buf, "%s %s", type, cmd->vict_found);
-						act_new(buf, ch, NULL, victim, TO_VICT, POS_DEAD);
-					}
-					channel_social(ch, victim, bitname,
-								   cmd->others_found, type,
-								   spec_flag, last_type);
-				}
-			}
-			return;
-		}
-		else if (!str_cmp(command, "!"))
-		{
-			fEmote = TRUE;
-
-			chprintlnf(ch, "%s %s %s{x", type,
-					   IS_NPC(ch) ? ch->short_descr : ch->name, argument);
-			update_last_data(ch, ch, last_type, type, argument, CHANNEL_EMOTE);
-		}
-		else if (!str_cmp(command, "wholist"))
-		{
-			display_wholist = TRUE;
-			chprintlnf(ch, "{WPlayers on %s{x", type);
-			chprintln(ch, "{C-------------------{x");
-		}
-		else if (!str_cmp(command, "-h") && !IS_NPC(ch) && last_type >= 0
-				 && last_type < LAST_MAX)
-		{
-			chprintlnf(ch, "{WLast %d messages on %s{x", LAST_PAGE_LENGTH,
-					   type);
-			chprintln(ch, "{C------------------------------{x");
-			view_last_data(ch, last_type);
-			return;
-		}
-		else
-		{
-			chprintlnf(ch, "%s You say '%s'{x", type, arg_left);
-			update_last_data(ch, ch, last_type, type, arg_left, CHANNEL_NORMAL);
-		}
-		for (d = descriptor_first; d != NULL; d = d->next)
-		{
-			CHAR_DATA *victim;
-
-			if (d->connected != CON_PLAYING)
-				continue;
-			if ((victim = d->character) == NULL)
-				continue;
-			if (victim == ch)
-				continue;
-			if ((bitname && IS_SET(victim->comm, (bitname)))
-				|| display_channel(ch, victim, spec_flag) == FALSE)
-				continue;
-
-			if (!display_wholist)
-			{
-				if (fEmote && !IS_SET(victim->comm, COMM_NOGOCIAL))
-				{
-					chprintlnf(victim, "%s %s %s{x", type,
-							   smash_colour(PERS(ch, victim)), argument);
-					update_last_data(ch, victim, last_type, type, argument,
-									 CHANNEL_EMOTE);
-				}
-				else
-				{
-					chprintlnf(victim, "%s %s says '%s'{x", type,
-							   smash_colour(PERS(ch, victim)), arg_left);
-					update_last_data(ch, victim, last_type, type, arg_left,
-									 CHANNEL_NORMAL);
-				}
-			}
-			else
-			{
-				if (victim->invis_level < LEVEL_IMMORTAL
-					&& victim->incog_level < LEVEL_IMMORTAL)
-					chprintlnf(ch, "{W%s{x", PERS(victim, ch));
-			}
-		}
-	}
-}
-
 CH_CMD(do_nogocial)
 {
 	set_on_off(ch, &ch->comm, COMM_NOGOCIAL,
@@ -418,80 +109,6 @@
 			   "You now see socials/emotes over channels.");
 }
 
-/* RT code to display channel status */
-
-CH_CMD(do_channels)
-{
-	/* lists all channels and their status */
-	chprintlnf(ch, " %-9s %-6s{w %s", "Command", "Status", "Description");
-	chprintln(ch, draw_line(ch, NULL, 0));
-
-	print_on_off(ch, !IS_SET(ch->comm, COMM_NOGOSSIP), "gossip",
-				 "Channel used in roleplay discussions.");
-	print_on_off(ch, !IS_SET(ch->comm, COMM_NOOOC), "ooc",
-				 "A global channel for Out Of Character discussions.");
-	print_on_off(ch, !IS_SET(ch->comm, COMM_NOAUCTION), "auction",
-				 "Channel for bartering goods.");
-	print_on_off(ch, !IS_SET(ch->comm, COMM_NOMUSIC), "music",
-				 "Global channel used for singing and jukebox songs.");
-	print_on_off(ch, !IS_SET(ch->comm, COMM_NOQUESTION), "Q/A",
-				 "Channel for asking and answering questions.");
-	print_on_off(ch, !IS_SET(ch->comm, COMM_NOQUOTE), "quote",
-				 "A global channel for \"quoting\" someone or something.");
-	print_on_off(ch, !IS_SET(ch->comm, COMM_NOGRATS), "grats",
-				 "A global channel for congratulating someone or something.");
-	print_on_off(ch, !IS_SET(ch->comm, COMM_NOBUDDY), "btalk",
-				 "A private channel that only transmits within buddies.");
-
-	if (IS_IMMORTAL(ch))
-	{
-		print_on_off(ch, !IS_SET(ch->comm, COMM_NOWIZ), "immtalk",
-					 "A global channel only for Immortals to use.");
-	}
-
-	print_on_off(ch, IS_SET(ch->comm, COMM_SHOUTSOFF), "shouts",
-				 "A global channel that transmits with a delay as if there is an echo.");
-	print_on_off(ch, IS_SET(ch->comm, COMM_DEAF), "deaf",
-				 "Prevents you from hearing any tells.");
-	print_on_off(ch, IS_SET(ch->comm, COMM_QUIET), "quiet",
-				 "Toggles whether you receive any channels at all.");
-	print_on_off(ch, IS_SET(ch->comm, COMM_AFK), "afk",
-				 "Sets you Away From Keyboard.");
-	print_on_off(ch, IS_SET(ch->comm, COMM_NOGOCIAL), "nogocial",
-				 "Toggles socials/emotes over public channels.");
-	chprintln(ch, draw_line(ch, NULL, 0));
-
-	if (IS_SET(ch->comm, COMM_SNOOP_PROOF))
-		chprintln(ch, "You are immune to snooping.");
-
-	if (ch->lines != PAGELEN)
-	{
-		if (ch->lines)
-		{
-			chprintlnf(ch, "You display %d lines of scroll.", ch->lines + 2);
-		}
-		else
-			chprintln(ch, "Scroll buffering is off.");
-	}
-
-	if (ch->prompt != NULL)
-	{
-		chprintlnf(ch, "Your current prompt is: %s", ch->prompt);
-	}
-
-	if (IS_SET(ch->comm, COMM_NOSHOUT))
-		chprintln(ch, "You cannot shout.");
-
-	if (IS_SET(ch->comm, COMM_NOTELL))
-		chprintln(ch, "You cannot use tell.");
-
-	if (IS_SET(ch->comm, COMM_NOCHANNELS))
-		chprintln(ch, "You cannot use channels.");
-
-	if (IS_SET(ch->comm, COMM_NOEMOTE))
-		chprintln(ch, "You cannot show emotions.");
-}
-
 /* RT deaf blocks out all shouts */
 
 CH_CMD(do_deaf)
@@ -521,8 +138,20 @@
 	}
 	else
 	{
-		chprintln(ch, "You are now in AFK mode.");
+		chprint(ch, "You are now in AFK mode. ");
 		SET_BIT(ch->comm, COMM_AFK);
+		if (!IS_NPC(ch))
+		{
+			char buf[MSL];
+
+			sprintf(buf, "[%s] %s", str_time(-1, GET_TZONE(ch), "%I:%M:%S %p"),
+					IS_NULLSTR(argument) ? "Please leave a message!" :
+					argument);
+			replace_string(ch->pcdata->afk_msg, buf);
+			chprintln(ch, ch->pcdata->afk_msg);
+		}
+		else
+			chprintln(ch, "");
 	}
 }
 
@@ -540,83 +169,25 @@
 		return;
 	}
 
-	page_to_char(buf_string(ch->pcdata->buffer), ch);
+	sendpage(ch, buf_string(ch->pcdata->buffer));
 	clear_buf(ch->pcdata->buffer);
 }
 
-/* RT chat replaced with ROM gossip */
-CH_CMD(do_gossip)
-{
-	public_ch(ch, argument, CTAG(_GOSSIP1) "[Gossip]" CTAG(_GOSSIP2),
-			  COMM_NOGOSSIP, spec_public_flag, LAST_GOSSIP);
-}
-
-CH_CMD(do_ooc)
-{
-	public_ch(ch, argument, "{C({WOOC{C){w", COMM_NOOOC, spec_public_flag,
-			  LAST_OOC);
-}
-
-CH_CMD(do_grats)
-{
-	public_ch(ch, argument, CTAG(_GRATS1) "[Grats]" CTAG(_GRATS2), COMM_NOGRATS,
-			  spec_public_flag, LAST_GRATS);
-}
-
-CH_CMD(do_quote)
-{
-	public_ch(ch, argument, CTAG(_QUOTE1) "[Quote]" CTAG(_QUOTE2), COMM_NOQUOTE,
-			  spec_public_flag, LAST_QUOTE);
-}
-
-/* RT question channel */
-CH_CMD(do_question)
-{
-	public_ch(ch, argument, CTAG(_QA1) "[Question]" CTAG(_QA2), COMM_NOQUESTION,
-			  spec_public_flag, LAST_QA);
-}
-
-/* RT answer channel - uses same line as questions */
-CH_CMD(do_answer)
-{
-	public_ch(ch, argument, CTAG(_QA1) "[Answer]" CTAG(_QA2), COMM_NOQUESTION,
-			  spec_public_flag, LAST_QA);
-}
-
-/* RT music channel */
-CH_CMD(do_music)
-{
-	public_ch(ch, argument,
-			  CTAG(_MUSIC1) "[" CTAG(_MUSIC2) "MUSIC" CTAG(_MUSIC1) "]"
-			  CTAG(_MUSIC3), COMM_NOMUSIC, spec_public_flag, LAST_MUSIC);
-}
-
 /* clan channels */
 CH_CMD(do_clantalk)
 {
-	char buf[MSL];
-
 	if (!is_clan(ch) || ch->clan->independent)
 	{
 		chprintln(ch, "You aren't in a clan.");
 		return;
 	}
 
-	sprintf(buf, "%s{W (%s)", ch->clan->who_name,
-			ch->clan->rank[ch->rank].rankname);
-	public_ch(ch, argument, buf, COMM_NOCLAN, spec_clan_flag, LAST_CLANTALK);
-}
-
-CH_CMD(do_immtalk)
-{
-	public_ch(ch, argument,
-			  CTAG(_IMMTALK1) "[" CTAG(_IMMTALK2) "ImmTalk" CTAG(_IMMTALK1) "]"
-			  CTAG(_IMMTALK3), COMM_NOWIZ, spec_imm_flag, LAST_IMMTALK);
+	public_ch(ch, argument, gcn_clan);
 }
 
 CH_CMD(do_say)
 {
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Say what?");
 		return;
@@ -667,7 +238,7 @@
 {
 	DESCRIPTOR_DATA *d;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		set_on_off(ch, &ch->comm, COMM_SHOUTSOFF, "You can hear shouts again.",
 				   "You will no longer hear shouts.");
@@ -694,6 +265,7 @@
 
 		if (d->connected == CON_PLAYING && d->character != ch &&
 			!IS_SET(victim->comm, COMM_SHOUTSOFF) &&
+			!is_ignoring(victim, ch->name, IGNORE_CHANNELS) &&
 			!IS_SET(victim->comm, COMM_QUIET))
 		{
 			act("" CTAG(_SHOUT1) "$n shouts '" CTAG(_SHOUT2) "$t"
@@ -706,8 +278,9 @@
 
 CH_CMD(do_tell)
 {
-	char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
+	char arg[MAX_INPUT_LENGTH];
 	CHAR_DATA *victim;
+	char buf[MSL];
 
 	if (IS_SET(ch->comm, COMM_NOTELL) || IS_SET(ch->comm, COMM_DEAF))
 	{
@@ -729,7 +302,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0' || argument[0] == '\0')
+	if (IS_NULLSTR(arg) || IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Tell whom what?");
 		return;
@@ -746,13 +319,19 @@
 		return;
 	}
 
+	if (is_ignoring(victim, ch->name, IGNORE_TELLS))
+	{
+		act_new("$N doesn't seem to be listening to you.", ch, NULL, victim,
+				TO_CHAR, POS_DEAD);
+		return;
+	}
+
 	if (victim->desc == NULL && !IS_NPC(victim))
 	{
 		act("$N seems to have misplaced $S link...try again later.", ch,
 			NULL, victim, TO_CHAR);
-		sprintf(buf, "%s tells you '%s'\n\r", PERS(ch, victim), argument);
-		buf[0] = UPPER(buf[0]);
-		add_buf(victim->pcdata->buffer, buf);
+		bprintlnf(victim->pcdata->buffer, "%s tells you '%s'\n\r",
+				  PERS(ch, victim), argument);
 		return;
 	}
 
@@ -778,18 +357,18 @@
 			return;
 		}
 
-		act("$E is AFK, but your tell will go through when $E returns.",
-			ch, NULL, victim, TO_CHAR);
-		sprintf(buf, "%s tells you '%s'\n\r", PERS(ch, victim), argument);
-		buf[0] = UPPER(buf[0]);
-		add_buf(victim->pcdata->buffer, buf);
+		act("$E is AFK ($t), but your tell will go through when $E returns.",
+			ch, victim->pcdata->afk_msg, victim, TO_CHAR);
+		bprintlnf(victim->pcdata->buffer, "%s tells you '%s'\n\r",
+				  PERS(ch, victim), argument);
 		return;
 	}
 
-	act("" CTAG(_TELLS1) "You tell $N '" CTAG(_TELLS2) "$t"
-		CTAG(_TELLS1) "'{x", ch, argument, victim, TO_CHAR);
-	act_new("" CTAG(_TELLS1) "$n tells you '" CTAG(_TELLS2) "$t"
-			CTAG(_TELLS1) "'{x", ch, argument, victim, TO_VICT, POS_DEAD);
+	act_new(CTAG(_TELLS1) "You tell $N '" CTAG(_TELLS2) "$t"
+			CTAG(_TELLS1) "'{x", ch, argument, victim, TO_CHAR, POS_DEAD);
+	sprintf(buf, CTAG(_TELLS1) MXPTAG("Tell '%s'") "$n" MXPTAG("/Tell")
+			" tells you '" CTAG(_TELLS2) "$t" CTAG(_TELLS1) "'{x", ch->name);
+	act_new(buf, ch, argument, victim, TO_VICT, POS_DEAD);
 	victim->reply = ch;
 
 	if (!IS_NPC(ch) && IS_NPC(victim) && HAS_TRIGGER_MOB(victim, TRIG_SPEECH))
@@ -802,7 +381,7 @@
 CH_CMD(do_reply)
 {
 	CHAR_DATA *victim;
-	char buf[MAX_STRING_LENGTH];
+	char buf[MSL];
 
 	if (IS_SET(ch->comm, COMM_NOTELL))
 	{
@@ -816,13 +395,19 @@
 		return;
 	}
 
+	if (is_ignoring(victim, ch->name, IGNORE_TELLS))
+	{
+		act_new("$N doesn't seem to be listening to you.", ch, NULL, victim,
+				TO_CHAR, POS_DEAD);
+		return;
+	}
+
 	if (victim->desc == NULL && !IS_NPC(victim))
 	{
 		act("$N seems to have misplaced $S link...try again later.", ch,
 			NULL, victim, TO_CHAR);
-		sprintf(buf, "%s tells you '%s'\n\r", PERS(ch, victim), argument);
-		buf[0] = UPPER(buf[0]);
-		add_buf(victim->pcdata->buffer, buf);
+		bprintlnf(victim->pcdata->buffer, "%s tells you '%s'\n\r",
+				  PERS(ch, victim), argument);
 		return;
 	}
 
@@ -856,16 +441,18 @@
 		}
 
 		act_new
-			("$E is AFK, but your tell will go through when $E returns.",
-			 ch, NULL, victim, TO_CHAR, POS_DEAD);
-		sprintf(buf, "%s tells you '%s'\n\r", PERS(ch, victim), argument);
-		buf[0] = UPPER(buf[0]);
-		add_buf(victim->pcdata->buffer, buf);
+			("$E is AFK ($t), but your tell will go through when $E returns.",
+			 ch, victim->pcdata->afk_msg, victim, TO_CHAR, POS_DEAD);
+		bprintlnf(victim->pcdata->buffer, "%s tells you '%s'", PERS(ch, victim),
+				  argument);
 		return;
 	}
 
-	act_new("You tell $N '$t'", ch, argument, victim, TO_CHAR, POS_DEAD);
-	act_new("$n tells you '$t'", ch, argument, victim, TO_VICT, POS_DEAD);
+	act_new(CTAG(_TELLS1) "You tell $N '" CTAG(_TELLS2) "$t"
+			CTAG(_TELLS1) "'{x", ch, argument, victim, TO_CHAR, POS_DEAD);
+	sprintf(buf, CTAG(_TELLS1) MXPTAG("Tell '%s'") "$n" MXPTAG("/Tell")
+			" tells you '" CTAG(_TELLS2) "$t" CTAG(_TELLS1) "'{x", ch->name);
+	act_new(buf, ch, argument, victim, TO_VICT, POS_DEAD);
 	victim->reply = ch;
 
 	return;
@@ -881,7 +468,7 @@
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Yell what?");
 		return;
@@ -893,6 +480,7 @@
 		if (d->connected == CON_PLAYING && d->character != ch &&
 			d->character->in_room != NULL &&
 			d->character->in_room->area == ch->in_room->area &&
+			!is_ignoring(d->character, ch->name, IGNORE_CHANNELS) &&
 			!IS_SET(d->character->comm, COMM_QUIET))
 		{
 			act("$n yells '$t'", ch, argument, d->character, TO_VICT);
@@ -910,7 +498,7 @@
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Emote what?");
 		return;
@@ -936,7 +524,7 @@
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Emote what?");
 		return;
@@ -1126,7 +714,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Follow whom?");
 		return;
@@ -1176,7 +764,7 @@
 {
 	if (ch->master != NULL)
 	{
-		bug("Add_follower: non-null master.", 0);
+		bug("Add_follower: non-null master.");
 		return;
 	}
 
@@ -1195,7 +783,7 @@
 {
 	if (ch->master == NULL)
 	{
-		bug("Stop_follower: null master.", 0);
+		bug("Stop_follower: null master.");
 		return;
 	}
 
@@ -1278,7 +866,7 @@
 		return;
 	}
 
-	if (arg[0] == '\0' || argument[0] == '\0')
+	if (IS_NULLSTR(arg) || IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Order whom to do what?");
 		return;
@@ -1350,7 +938,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		CHAR_DATA *gch;
 		CHAR_DATA *leader;
@@ -1441,7 +1029,7 @@
 	argument = one_argument(argument, arg1);
 	one_argument(argument, arg2);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		chprintln(ch, "Split how much?");
 		return;
@@ -1449,7 +1037,7 @@
 
 	amount_silver = atoi(arg1);
 
-	if (arg2[0] != '\0')
+	if (!IS_NULLSTR(arg2))
 		amount_gold = atoi(arg2);
 
 	if (amount_gold < 0 || amount_silver < 0)
@@ -1549,7 +1137,7 @@
 {
 	CHAR_DATA *gch;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Tell your group what?");
 		return;
@@ -1617,34 +1205,32 @@
 	return;
 }
 
-int attribute_lookup(const char *arg)
+const struct colour_type *get_col_table(int type)
 {
-	int i;
-
-	for (i = 0; colour_attributes[i].name != NULL; i++)
-		if (!str_prefix(arg, colour_attributes[i].name))
-			return i;
-
-	return -1;
+	switch (type)
+	{
+	case CT_ATTR:
+		return colour_attributes;
+	case CT_FORE:
+		return colour_foregrounds;
+	case CT_BACK:
+		return colour_backgrounds;
+	default:
+		bug("bad type");
+		return NULL;
+	}
 }
 
-int foreground_lookup(const char *arg)
+int ctype_lookup(const char *arg, int type)
 {
 	int i;
+	const struct colour_type *table = get_col_table(type);
 
-	for (i = 0; colour_foregrounds[i].name != NULL; i++)
-		if (!str_prefix(arg, colour_foregrounds[i].name))
-			return i;
+	if (!table)
+		return -1;
 
-	return -1;
-}
-
-int background_lookup(const char *arg)
-{
-	int i;
-
-	for (i = 0; colour_backgrounds[i].name != NULL; i++)
-		if (!str_prefix(arg, colour_backgrounds[i].name))
+	for (i = 0; table[i].name != NULL; i++)
+		if (!str_prefix(arg, table[i].name))
 			return i;
 
 	return -1;
@@ -1661,11 +1247,11 @@
 	{
 		for (i = 0; i < MAX_CUSTOM_COLOUR; i++)
 		{
-			ch->pcdata->colour[cslot_table[i].slot][0] =
+			ch->pcdata->colour[cslot_table[i].slot][CT_ATTR] =
 				cslot_table[i].col_attr;
-			ch->pcdata->colour[cslot_table[i].slot][1] =
+			ch->pcdata->colour[cslot_table[i].slot][CT_FORE] =
 				cslot_table[i].col_fore;
-			ch->pcdata->colour[cslot_table[i].slot][2] =
+			ch->pcdata->colour[cslot_table[i].slot][CT_BACK] =
 				cslot_table[i].col_back;
 		}
 	}
@@ -1675,9 +1261,9 @@
 		{
 			if (cslot_table[i].slot == slot)
 			{
-				ch->pcdata->colour[slot][0] = cslot_table[i].col_attr;
-				ch->pcdata->colour[slot][1] = cslot_table[i].col_fore;
-				ch->pcdata->colour[slot][2] = cslot_table[i].col_back;
+				ch->pcdata->colour[slot][CT_ATTR] = cslot_table[i].col_attr;
+				ch->pcdata->colour[slot][CT_FORE] = cslot_table[i].col_fore;
+				ch->pcdata->colour[slot][CT_BACK] = cslot_table[i].col_back;
 				break;
 			}
 		}
@@ -1688,7 +1274,7 @@
 
 const char *char_colour(CHAR_DATA * ch, int slot)
 {
-	extern int col_attr, col_fore, col_back;
+	EXTERN int col_attr, col_fore, col_back;
 
 	if (!ch || !ch->desc || IS_NPC(ch) || slot < 0 || slot >= MAX_CUSTOM_COLOUR)
 	{
@@ -1698,9 +1284,9 @@
 		return CL_DEFAULT;
 	}
 
-	col_attr = ch->pcdata->colour[slot][0];
-	col_fore = ch->pcdata->colour[slot][1];
-	col_back = ch->pcdata->colour[slot][2];
+	col_attr = ch->pcdata->colour[slot][CT_ATTR];
+	col_fore = ch->pcdata->colour[slot][CT_FORE];
+	col_back = ch->pcdata->colour[slot][CT_BACK];
 
 	return make_colour();
 }
@@ -1832,27 +1418,27 @@
 			return;
 		}
 
-		if ((c_attr = attribute_lookup(attr)) == -1)
+		if ((c_attr = ctype_lookup(attr, CT_ATTR)) == -1)
 		{
 			chprintln(ch, "Invalid Colour Attribute.");
 			return;
 		}
 
-		if ((c_fore = foreground_lookup(fore)) == -1)
+		if ((c_fore = ctype_lookup(fore, CT_FORE)) == -1)
 		{
 			chprintln(ch, "Invalid Foreground Colour.");
 			return;
 		}
 
-		if ((c_back = background_lookup(back)) == -1)
+		if ((c_back = ctype_lookup(back, CT_BACK)) == -1)
 		{
 			chprintln(ch, "Invalid background Colour.");
 			return;
 		}
 
-		ch->pcdata->colour[slot][0] = colour_attributes[c_attr].col_type;
-		ch->pcdata->colour[slot][1] = colour_foregrounds[c_fore].col_type;
-		ch->pcdata->colour[slot][2] = colour_backgrounds[c_back].col_type;
+		ch->pcdata->colour[slot][CT_ATTR] = colour_attributes[c_attr].col_type;
+		ch->pcdata->colour[slot][CT_FORE] = colour_foregrounds[c_fore].col_type;
+		ch->pcdata->colour[slot][CT_BACK] = colour_backgrounds[c_back].col_type;
 		chprintlnf(ch, "%s set to %s%s %s, with %s background{x.",
 				   cslot_table[slot].name, char_colour(ch, slot),
 				   colour_attributes[c_attr].name,
@@ -1862,6 +1448,17 @@
 	}
 }
 
+flag_t ignore_bit(flag_t info)
+{
+	switch (info)
+	{
+	case INFO_LEVEL:
+		return IGNORE_LEVELS;
+	default:
+		return IGNORE_ANNOUNCE;
+	}
+}
+
 void announce(CHAR_DATA * ch, flag_t bit, const char *message, ...)
 {
 	DESCRIPTOR_DATA *d;
@@ -1870,6 +1467,9 @@
 	bool Private = FALSE;
 	va_list args;
 
+	if (IS_NULLSTR(message))
+		return;
+
 	va_start(args, message);
 	vsnprintf(buf2, sizeof(buf2), message, args);
 	va_end(args);
@@ -1915,7 +1515,7 @@
 
 			if (ch == NULL)
 				chprintln(och, buf);
-			else
+			else if (!is_ignoring(och, ch->name, ignore_bit(bit)))
 				act_new(buf, ch, NULL, och, TO_VICT, POS_DEAD);
 		}
 	}
@@ -1923,7 +1523,7 @@
 	{
 		if (!ch)
 		{
-			bug("NULL ch in private announce", 0);
+			bug("NULL ch in private announce");
 			return;
 		}
 		chprintln(ch, buf);
diff -ur -x config -x o -x rom src/act_enter.c new/act_enter.c
--- src/act_enter.c	Tue May 27 02:46:35 2003
+++ new/act_enter.c	Sun Aug 31 19:23:20 2003
@@ -22,17 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "interp.h"
 #include "lookup.h"
@@ -74,7 +67,7 @@
 		return;
 
 	/* nifty portal stuff */
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		ROOM_INDEX_DATA *old_room;
 		OBJ_DATA *portal;
diff -ur -x config -x o -x rom src/act_info.c new/act_info.c
--- src/act_info.c	Tue May 27 02:46:35 2003
+++ new/act_info.c	Sun Aug 31 19:23:20 2003
@@ -22,19 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "magic.h"
@@ -43,41 +34,37 @@
 #include "lookup.h"
 
 char *const where_name[] = {
-	"<used as light>     ",
-	"<worn on finger>    ",
-	"<worn on finger>    ",
-	"<worn around neck>  ",
-	"<worn around neck>  ",
-	"<worn on torso>     ",
-	"<worn on head>      ",
-	"<worn on legs>      ",
-	"<worn on feet>      ",
-	"<worn on hands>     ",
-	"<worn on arms>      ",
-	"<worn as shield>    ",
-	"<worn about body>   ",
-	"<worn about waist>  ",
-	"<worn around wrist> ",
-	"<worn around wrist> ",
-	"<wielded>           ",
-	"<held>              ",
-	"<floating nearby>   ",
-	"<secondary weapon>  "
+	"{g<{Wused as light{g>{x     ",
+	"{g<{Wworn on finger{g>{x    ",
+	"{g<{Wworn on finger{g>{x    ",
+	"{g<{Wworn around neck{g>{x  ",
+	"{g<{Wworn around neck{g>{x  ",
+	"{g<{Wworn on torso{g>{x     ",
+	"{g<{Wworn on head{g>{x      ",
+	"{g<{Wworn on legs{g>{x      ",
+	"{g<{Wworn on feet{g>{x      ",
+	"{g<{Wworn on hands{g>{x     ",
+	"{g<{Wworn on arms{g>{x      ",
+	"{g<{Wworn as shield{g>{x    ",
+	"{g<{Wworn about body{g>{x   ",
+	"{g<{Wworn about waist{g>{x  ",
+	"{g<{Wworn around wrist{g>{x ",
+	"{g<{Wworn around wrist{g>{x ",
+	"{g<{Wwielded{g>{x           ",
+	"{g<{Wheld{g>{x              ",
+	"{g<{Wfloating nearby{g>{x   ",
+	"{g<{Wsecondary weapon{g>{x  "
 };
 
-/* for  keeping track of the player count */
-int max_on = 0;
-
 /*
  * Local functions.
  */
-char *format_obj_to_char args((OBJ_DATA * obj, CHAR_DATA * ch, bool fShort));
-void show_list_to_char
-args((OBJ_DATA * list, CHAR_DATA * ch, bool fShort, bool fShowNothing));
-void show_char_to_char_0 args((CHAR_DATA * victim, CHAR_DATA * ch));
-void show_char_to_char_1 args((CHAR_DATA * victim, CHAR_DATA * ch));
-void show_char_to_char args((CHAR_DATA * list, CHAR_DATA * ch));
-bool check_blind args((CHAR_DATA * ch));
+PROTOTYPE(char *format_obj_to_char, (OBJ_DATA *, CHAR_DATA *, bool));
+PROTOTYPE(void show_list_to_char, (OBJ_DATA *, CHAR_DATA *, bool, bool));
+PROTOTYPE(void show_char_to_char_0, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void show_char_to_char_1, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void show_char_to_char, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool check_blind, (CHAR_DATA *));
 
 char *format_obj_to_char(OBJ_DATA * obj, CHAR_DATA * ch, bool fShort)
 {
@@ -86,8 +73,7 @@
 	buf[0] = '\0';
 
 	if ((fShort &&
-		 (obj->short_descr == NULL || obj->short_descr[0] == '\0')) ||
-		(obj->description == NULL || obj->description[0] == '\0'))
+		 IS_NULLSTR(obj->short_descr)) || IS_NULLSTR(obj->description))
 		return buf;
 
 	if (IS_OBJ_STAT(obj, ITEM_INVIS))
@@ -127,7 +113,6 @@
 void show_list_to_char(OBJ_DATA * list, CHAR_DATA * ch, bool fShort,
 					   bool fShowNothing)
 {
-	char buf[MAX_STRING_LENGTH];
 	BUFFER *output;
 	const char **prgpstrShow;
 	int *prgnShow;
@@ -208,16 +193,14 @@
 		{
 			if (prgnShow[iShow] != 1)
 			{
-				sprintf(buf, "(%2d) ", prgnShow[iShow]);
-				add_buf(output, buf);
+				bprintf(output, "(%2d) ", prgnShow[iShow]);
 			}
 			else
 			{
-				add_buf(output, "     ");
+				bprint(output, "     ");
 			}
 		}
-		add_buf(output, prgpstrShow[iShow]);
-		add_buf(output, "\n\r");
+		bprintln(output, prgpstrShow[iShow]);
 		free_string(prgpstrShow[iShow]);
 	}
 
@@ -227,7 +210,7 @@
 			chprint(ch, "     ");
 		chprintln(ch, "Nothing.");
 	}
-	page_to_char(buf_string(output), ch);
+	sendpage(ch, buf_string(output));
 
 	/*
 	 * Clean up.
@@ -281,7 +264,8 @@
 		strcat(buf, "{Y({RGquest{Y){x ");
 	}
 
-	if (victim->position == victim->start_pos && victim->long_descr[0] != '\0')
+	if (victim->position == victim->start_pos
+		&& !IS_NULLSTR(victim->long_descr))
 	{
 		strcat(buf, victim->long_descr);
 		chprint(ch, buf);
@@ -415,6 +399,8 @@
 		else
 			strcat(buf, "someone who left??");
 		break;
+	default:
+		break;
 	}
 
 	buf[0] = UPPER(buf[0]);
@@ -441,7 +427,7 @@
 		}
 	}
 
-	if (victim->description[0] != '\0')
+	if (!IS_NULLSTR(victim->description))
 	{
 		chprint(ch, victim->description);
 	}
@@ -480,7 +466,8 @@
 	found = FALSE;
 	for (iWear = 0; iWear < MAX_WEAR; iWear++)
 	{
-		if ((obj = get_eq_char(victim, iWear)) != NULL && can_see_obj(ch, obj))
+		if ((obj = get_eq_char(victim, (wloc_t) iWear)) != NULL
+			&& can_see_obj(ch, obj))
 		{
 			if (!found)
 			{
@@ -544,50 +531,114 @@
 	return TRUE;
 }
 
-/* changes your scroll */
-CH_CMD(do_scroll)
+int get_scr_cols(CHAR_DATA * ch)
 {
-	char arg[MAX_INPUT_LENGTH];
-	int lines;
+	unsigned int len;
 
-	one_argument(argument, arg);
+	if (!ch)
+		len = DEFAULT_SCR_WIDTH;
+	else if (ch->columns <= 10)
+		len = SCR_WIDTH(ch->desc);
+	else
+		len = ch->columns;
+
+	return len - 2;
+}
+
+int get_scr_lines(CHAR_DATA * ch)
+{
+	unsigned int len;
 
-	if (arg[0] == '\0')
+	if (!ch)
+		len = DEFAULT_SCR_HEIGHT;
+	else if (!ch->lines)
+		len = SCR_HEIGHT(ch->desc);
+	else
+		len = ch->lines;
+
+	return len - 2;
+}
+
+CH_CMD(do_screen)
+{
+	char arg1[MIL], arg2[MIL];
+	unsigned int lines;
+	int *plines;
+	char *func;
+	unsigned int def_lines;
+
+	argument = one_argument(argument, arg1);
+	one_argument(argument, arg2);
+
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
 	{
-		if (ch->lines == 0)
+		if (get_scr_lines(ch) < 0)
 			chprintln(ch, "You do not page long messages.");
 		else
 		{
-			chprintlnf(ch,
-					   "You currently display %d lines per page.",
-					   ch->lines + 2);
+			chprintlnf(ch, "You currently display %d lines per page.",
+					   get_scr_lines(ch));
+		}
+		chprintlnf(ch, "\n\rYou currently display %d columns per line.",
+				   get_scr_cols(ch));
+		chprintln(ch, "\n\rSyntax: screen lines|columns <#val|default>");
+		chprintlnf(ch,
+				   "        (type 'screen lines none' to disable scrolling)");
+		return;
+	}
+	if (!str_prefix(arg1, "lines"))
+	{
+		if (!str_cmp(arg2, "none") || atoi(arg2) < 0)
+		{
+			ch->lines = -1;
+			chprintln
+				(ch,
+				 "Scrolling disabled.  This may cause you to disconnect on long outputs.");
+			return;
 		}
+		plines = &ch->lines;
+		func = "lines";
+		def_lines = SCR_HEIGHT(ch->desc);
+	}
+	else if (!str_prefix(arg1, "columns"))
+	{
+		plines = &ch->columns;
+		func = "columns";
+		def_lines = SCR_WIDTH(ch->desc);
+	}
+	else
+	{
+		do_screen(ch, "");
 		return;
 	}
 
-	if (!is_number(arg))
+	if (!str_cmp(arg2, "default"))
 	{
-		chprintln(ch, "You must provide a number.");
+		*plines = def_lines;
+		chprintlnf(ch, "You're screen now displays %d %s.", def_lines, func);
 		return;
 	}
-
-	lines = atoi(arg);
-
-	if (lines == 0)
+	else if (!is_number(arg2))
 	{
-		chprintln(ch, "Paging disabled.");
-		ch->lines = 0;
+		chprintln(ch, "You must provide a number.");
 		return;
 	}
 
-	if (lines < 10 || lines > 100)
+	lines = atoi(arg2);
+
+	if (lines < 10 || lines > 250)
 	{
 		chprintln(ch, "You must provide a reasonable number.");
 		return;
 	}
 
-	chprintlnf(ch, "Scroll set to %d lines.", lines);
-	ch->lines = lines - 2;
+	chprintlnf(ch, "Your screen now displays %d %s.", lines, func);
+	if (ch->desc && IS_SET(ch->desc->d_flags, DESC_TELOPT_NAWS)
+		&& lines != def_lines)
+		chprintlnf
+			(ch, "The MUD has detected that you have %d screen %s.",
+			 def_lines, func);
+	*plines = lines;
 }
 
 /* RT does socials */
@@ -774,14 +825,21 @@
 {
 	char buf[MAX_STRING_LENGTH];
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		set_on_off(ch, &ch->comm, COMM_PROMPT, "You will now see prompts.",
 				   "You will no longer see prompts.");
 		return;
 	}
 
-	if (!str_cmp(argument, "all"))
+	else if (!str_prefix(argument, "autoprompt"))
+	{
+		set_on_off(ch, &ch->act, PLR_AUTOPROMPT,
+				   "Prompts will now always show.",
+				   "Prompts are now selectivly shown.");
+		return;
+	}
+	else if (!str_cmp(argument, "all"))
 		strcpy(buf, "<%hhp %mm %vmv> ");
 	else
 	{
@@ -794,8 +852,7 @@
 
 	}
 
-	free_string(ch->prompt);
-	ch->prompt = str_dup(buf);
+	replace_string(ch->prompt, buf);
 	chprintlnf(ch, "Prompt set to %s", ch->prompt);
 	return;
 }
@@ -868,52 +925,6 @@
 	return FALSE;
 }
 
-unsigned int get_line args((char *desc, unsigned int max_len));
-void reformat_desc args((char *desc));
-
-void show_desc(CHAR_DATA * ch, const char *desc)
-{
-	static char buf[MSL * 2];
-	static char out[MSL * 2];
-	int width;
-	unsigned int pos;
-	char *p;
-	bool alldesc = FALSE;
-
-	width = 78;
-
-	if (ch->desc != NULL && ch->desc->scr_width > 0)
-		width = ch->desc->scr_width - 2;
-
-	sprintf(buf, "%s", desc);
-	reformat_desc(buf);
-
-	p = &buf[0];
-	pos = 0;
-
-	out[0] = '\0';
-
-	do
-	{
-		pos = get_line(p, width);
-		if (pos > 0)
-		{
-			strncat(out, p, pos);
-			p += pos;
-		}
-		else
-		{
-			strcat(out, p);
-			alldesc = TRUE;
-		}
-		strcat(out, "\n\r");
-	}
-	while (!alldesc);
-
-	chprint(ch, out);
-	return;
-}
-
 CH_CMD(do_look)
 {
 	char buf[MAX_STRING_LENGTH];
@@ -958,10 +969,12 @@
 	number = number_argument(arg1, arg3);
 	count = 0;
 
-	if (arg1[0] == '\0' || !str_cmp(arg1, "auto"))
+	if (IS_NULLSTR(arg1) || !str_cmp(arg1, "auto"))
 	{
 		/* 'look' or 'look auto' */
+		chprint(ch, MXPTAG("RName"));
 		chprintf(ch, "" CTAG(_RTITLE) "%s", ch->in_room->name);
+		chprint(ch, MXPTAG("/RName"));
 
 		if ((IS_IMMORTAL(ch) &&
 			 (IS_NPC(ch) || IS_SET(ch->act, PLR_HOLYLIGHT))) ||
@@ -972,10 +985,11 @@
 
 		chprintln(ch, "{x");
 
-		if (arg1[0] == '\0' || (!IS_NPC(ch) && !IS_SET(ch->comm, COMM_BRIEF)))
+		if (IS_NULLSTR(arg1) || (!IS_NPC(ch) && !IS_SET(ch->comm, COMM_BRIEF)))
 		{
 			if (is_last_run(ch))
 			{
+				chprint(ch, MXPTAG("RDesc"));
 				if (!IS_SET(ch->in_room->room_flags, ROOM_NOAUTOMAP)
 					&& !IS_NPC(ch) && IS_SET(ch->act, PLR_AUTOMAP))
 				{
@@ -987,12 +1001,12 @@
 				}
 				else
 				{
-					sprintf(buf, "%s%s{x",
-							get_sector_color(ch->in_room->sector_type),
-							IS_NULLSTR(ch->in_room->description) ?
-							"No room description!" : ch->in_room->description);
-					show_desc(ch, buf);
+					dwraplnf(ch->desc, "%s%s{x",
+							 get_sector_color(ch->in_room->sector_type),
+							 IS_NULLSTR(ch->in_room->description) ?
+							 "No room description!" : ch->in_room->description);
 				}
+				chprint(ch, MXPTAG("/RDesc"));
 			}
 		}
 
@@ -1010,7 +1024,7 @@
 	if (!str_cmp(arg1, "i") || !str_cmp(arg1, "in") || !str_cmp(arg1, "on"))
 	{
 		/* 'look in' */
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			chprintln(ch, "Look in what?");
 			return;
@@ -1179,13 +1193,12 @@
 		return;
 	}
 
-	if (pexit->description != NULL && pexit->description[0] != '\0')
+	if (!IS_NULLSTR(pexit->description))
 		chprint(ch, pexit->description);
 	else
 		chprintln(ch, "Nothing special there.");
 
-	if (pexit->keyword != NULL && pexit->keyword[0] != '\0' &&
-		pexit->keyword[0] != ' ')
+	if (!IS_NULLSTR(pexit->keyword) && pexit->keyword[0] != ' ')
 	{
 		if (IS_SET(pexit->exit_info, EX_CLOSED))
 		{
@@ -1214,7 +1227,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Examine what?");
 		return;
@@ -1289,7 +1302,7 @@
 		return;
 
 	if (fAuto)
-		sprintf(buf, "[Exits:");
+		sprintf(buf, "[Exits:" MXPTAG("RExits"));
 	else if (IS_IMMORTAL(ch))
 		sprintf(buf, "Obvious exits from room %ld:\n\r", ch->in_room->vnum);
 	else
@@ -1306,8 +1319,9 @@
 			found = TRUE;
 			if (fAuto)
 			{
-				strcat(buf, " ");
+				strcat(buf, " " MXPTAG("Ex"));
 				strcat(buf, dir_name[door]);
+				strcat(buf, MXPTAG("/Ex"));
 			}
 			else
 			{
@@ -1328,7 +1342,7 @@
 		strcat(buf, fAuto ? " none" : "None.\n\r");
 
 	if (fAuto)
-		strcat(buf, "]");
+		strcat(buf, MXPTAG("/RExits") "]");
 
 	chprintln(ch, buf);
 	return;
@@ -1506,8 +1520,17 @@
 	case POS_FIGHTING:
 		chprintln(ch, "" CTAG(_SCORE1) "You are " CTAG(_SCORE3) "fighting.{x");
 		break;
+	default:
+		break;
 	}
 
+	if (IS_VALID_STANCE(GET_STANCE(ch, STANCE_AUTODROP)))
+		chprintlnf(ch,
+				   CTAG(_SCORE1) "You auto-drop into the " CTAG(_SCORE3) "%s"
+				   CTAG(_SCORE1) " stance. (" CTAG(_SCORE3) "%d%%" CTAG(_SCORE1)
+				   "){x", get_stance_name(GET_STANCE(ch, STANCE_AUTODROP)),
+				   GET_STANCE(ch, GET_STANCE(ch, STANCE_AUTODROP)));
+
 	/* print AC values */
 	if (ch->level >= 25)
 	{
@@ -1639,39 +1662,149 @@
 CH_CMD(do_affects)
 {
 	AFFECT_DATA *paf, *paf_last = NULL;
-	char buf[MAX_STRING_LENGTH];
+	const char *buf4;
+	char buf3[MSL];
+	char buf2[MSL];
+	bool found = FALSE;
+	flag_t filter;
+	flag_t printme;
+	BUFFER *buffer;
+	OBJ_DATA *obj;
+	int iWear;
+
+	buffer = new_buf();
 
 	if (ch->first_affect != NULL)
 	{
-		chprintln(ch, "You are affected by the following spells:");
+		bprintln(buffer, "You are affected by the following spells:{x");
+
 		for (paf = ch->first_affect; paf != NULL; paf = paf->next)
 		{
 			if (paf_last != NULL && paf->type == paf_last->type)
-				if (ch->level >= 20)
-					chprint(ch, "                      ");
+			{
+				if (get_trust(ch) >= 20)
+					bprint(buffer, "                          ");
 				else
 					continue;
+			}
 			else
-				chprintf(ch, "Spell: %-15s", skill_table[paf->type].name);
+				bprintf(buffer, "{xSpell: {c%-19s{x",
+						(paf->type != -1
+						 && !IS_NULLSTR(skill_table[paf->type].name))
+						? skill_table[paf->type].name : "unknown");
 
-			if (ch->level >= 20)
+			if (get_trust(ch) >= 20)
 			{
-				sprintf(buf, ": modifies %s by %d ",
+				bprintf(buffer, ": {xmodifies %s by %d{x ",
 						flag_string(apply_flags, paf->location), paf->modifier);
-				chprint(ch, buf);
 				if (paf->duration == -1)
-					chprint(ch, "permanently");
+					bprint(buffer, "{xpermanently{x");
 				else
-					chprintf(ch, "for %d hours", paf->duration);
+					bprintf(buffer, "{xfor %d hours{x", paf->duration);
 			}
 
-			chprintln(ch, "");
+			bprintln(buffer, "");
 			paf_last = paf;
 		}
+		found = TRUE;
+		bprintln(buffer, "");
 	}
-	else
-		chprintln(ch, "You are not affected by any spells.");
+	if (ch->race->aff != 0 && IS_AFFECTED(ch, ch->race->aff))
+	{
+		bprintln(buffer,
+				 "You are affected by the following racial abilities:{x");
+
+		strcpy(buf3, flag_string(affect_flags, ch->race->aff));
+		buf4 = buf3;
+		buf4 = one_argument(buf4, buf2);
+		while (buf2[0])
+		{
+			bprintlnf(buffer, "{xSpell: {c%-19s{x", buf2);
+			buf4 = one_argument(buf4, buf2);
+		}
+		found = TRUE;
+		bprintln(buffer, "");
+	}
+	if (ch->affected_by != 0 && (ch->affected_by != ch->race->aff))
+	{
+		bool print = FALSE;
+
+		for (iWear = 0; iWear < MAX_WEAR; iWear++)
+		{
+			if ((obj = get_eq_char(ch, (wloc_t) iWear)) != NULL)
+			{
+				for (paf = obj->first_affect; paf != NULL; paf = paf->next)
+				{
+					if (!IS_SET(ch->affected_by, paf->bitvector))
+						continue;
+
+					if (paf->where != TO_AFFECTS)
+						continue;
+
+					filter = paf->bitvector;
+					filter &= ch->affected_by;
+					printme = filter;
+					if (!print)
+					{
+						bprintln(buffer,
+								 "You are affected by the following equipment spells:{x");
+						print = TRUE;
+					}
+
+					strcpy(buf3, flag_string(affect_flags, printme));
+					buf4 = buf3;
+					buf4 = one_argument(buf4, buf2);
+					while (buf2[0])
+					{
+						bprintlnf(buffer, "{xSpell: {c%-19s:{x %s", buf2,
+								  obj->short_descr);
+						buf4 = one_argument(buf4, buf2);
+					}
+				}
+				if (!obj->enchanted)
+				{
+					for (paf = obj->pIndexData->first_affect; paf != NULL;
+						 paf = paf->next)
+					{
+						if (!IS_SET(ch->affected_by, paf->bitvector))
+							continue;
+						if (paf->where != TO_AFFECTS)
+							continue;
+						filter = paf->bitvector;
+						filter &= ch->affected_by;
+						printme = filter;
+						if (!print)
+						{
+							bprintln(buffer,
+									 "You are affected by the following equipment spells:{x");
+							print = TRUE;
+						}
+
+						strcpy(buf3, flag_string(affect_flags, printme));
 
+						buf4 = buf3;
+						buf4 = one_argument(buf4, buf2);
+						while (buf2[0])
+						{
+							bprintlnf(buffer, "{xSpell: {c%-19s:{x %s", buf2,
+									  obj->short_descr);
+							buf4 = one_argument(buf4, buf2);
+						}
+					}
+				}
+			}
+		}
+		found = TRUE;
+		if (print)
+			bprintln(buffer, "");
+	}
+	if (!found)
+	{
+		bprintln(buffer, "You are not affected by any spells.{x");
+	}
+
+	sendpage(ch, buf_string(buffer));
+	free_buf(buffer);
 	return;
 }
 
@@ -1680,7 +1813,7 @@
 	"the Great Gods", "the Sun"
 };
 
-char *const month_name[] = {
+char *const month_name[NUM_MONTHS] = {
 	"Winter", "the Winter Wolf", "the Frost Giant", "the Old Forces",
 	"the Grand Struggle", "the Spring", "Nature", "Futility", "the Dragon",
 	"the Sun", "the Heat", "the Battle", "the Dark Shades", "the Shadows",
@@ -1689,7 +1822,6 @@
 
 CH_CMD(do_time)
 {
-	extern char str_boot_time[];
 	char *suf;
 	int day;
 
@@ -1729,16 +1861,47 @@
 			   (time_info.hour % 12 == 0) ? 12 : time_info.hour % 12,
 			   time_info.hour >= 12 ? "pm" : "am", day_name[day % 7], day,
 			   suf, month_name[time_info.month]);
-	chprintlnf(ch, "ROM started up at %s\n\rThe system time is %s.",
-			   str_boot_time, str_time(current_time, -1, NULL));
+	chprintlnf(ch,
+			   MUD_NAME
+			   " started up at %s\n\rWhich was %s ago.\n\rThe system time is %s.",
+			   str_time(boot_time, -1, NULL), timestr(current_time - boot_time,
+													  FALSE), str_time(-1, -1,
+																	   NULL));
 
-	if (GET_TZONE(ch) != -1)
-		chprintlnf(ch, "Your local time is %s",
-				   str_time(current_time, GET_TZONE(ch), NULL));
-	else
-		chprintln
-			(ch,
-			 "Your local time is not set! Use the 'timezone' command to set your time zone.");
+	if (!IS_NPC(ch))
+	{
+		if (GET_TZONE(ch) != -1)
+			chprintlnf(ch, "Your local time is %s",
+					   str_time(-1, GET_TZONE(ch), NULL));
+		else
+			chprintln
+				(ch,
+				 "Your local time is not set! Use the 'timezone' command to set your time zone.");
+
+		// online time
+		chprintlnf(ch, "You connected at %s\n\rWhich was %s ago.",
+				   str_time(ch->logon, GET_TZONE(ch), NULL),
+				   timestr(current_time - ch->logon, FALSE));
+		// creation time
+		chprintlnf(ch, "You first created at %s\n\r"
+				   "Which was %s ago.",
+				   str_time(ch->id, GET_TZONE(ch), NULL),
+				   timestr(current_time - ch->id, FALSE));
+
+		chprintlnf(ch, "You have played approximately %d.%02d hours.",
+				   (ch->played + (int) (current_time - ch->logon)) / HOUR,
+				   ((ch->played + (int) (current_time - ch->logon)) / 36) %
+				   100);
+
+		chprintlnf
+			(ch, "Which is %0.03f%% of the time since you created.",
+			 ((double) (ch->played + (int) (current_time - ch->logon)) /
+			  (double) (current_time - ch->id)) * 100.0);
+	}
+	if (crs_info.timer > -1 && crs_info.status != CRS_NONE)
+	{
+		chprintln(ch, crs_sprintf(TRUE, FALSE));
+	}
 
 	return;
 }
@@ -1780,24 +1943,34 @@
 
 CH_CMD(do_weather)
 {
-
-	static char *const sky_look[4] = {
-		"cloudless",
-		"cloudy",
-		"rainy",
-		"lit by flashes of lightning"
-	};
+	char *combo = "", *single = "";
+	int temp, precip, wind;
 
 	if (!IS_OUTSIDE(ch))
 	{
-		chprintln(ch, "You can't see the weather indoors.");
+		chprintln(ch, "You can't see the sky from here.");
 		return;
 	}
 
-	chprintlnf(ch, "The sky is %s and %s.", sky_look[weather_info.sky],
-			   weather_info.change >=
-			   0 ? "a warm southerly breeze blows" :
-			   "a cold northern gust blows");
+	temp = (ch->in_room->area->weather.temp + 3 * mud_info.weath_unit - 1) /
+		mud_info.weath_unit;
+	precip = (ch->in_room->area->weather.precip + 3 * mud_info.weath_unit - 1) /
+		mud_info.weath_unit;
+	wind = (ch->in_room->area->weather.wind + 3 * mud_info.weath_unit - 1) /
+		mud_info.weath_unit;
+
+	if (precip >= 3)
+	{
+		combo = preciptemp_msg[precip][temp];
+		single = wind_msg[wind];
+	}
+	else
+	{
+		combo = windtemp_msg[wind][temp];
+		single = precip_msg[precip];
+	}
+
+	chprintlnf(ch, "{B%s and %s.{x", combo, single);
 	return;
 }
 
@@ -1818,7 +1991,6 @@
 	BUFFER *buffer;
 	BUFFER *related;
 	int counter = 0, number, count = 0;
-	char buf[MSL];
 
 	if (IS_NULLSTR(argument))
 		argument = "summary";
@@ -1827,7 +1999,7 @@
 	while (!IS_NULLSTR(argument))
 	{
 		argument = one_argument(argument, argone);
-		if (argall[0] != '\0')
+		if (!IS_NULLSTR(argall))
 			strcat(argall, " ");
 		strcat(argall, argone);
 	}
@@ -1850,76 +2022,65 @@
 		{
 			counter++;
 
-			sprintf(buf, "%3d) %s\n\r", counter, pHelp->keyword);
-			add_buf(buffer, buf);
+			bprintlnf(buffer, "%3d) "
+					  MXPTAG("Help '%s'") "%s" MXPTAG("/Help"), counter,
+					  pHelp->keyword, pHelp->keyword);
 			list = TRUE;
 			found = TRUE;
 			continue;
 		}
 		if (found)
 		{
-			sprintf(buf, "%s, ", pHelp->keyword);
-			add_buf(related, buf);
+			bprintf(buffer, "%s, ", pHelp->keyword);
 			continue;
 		}
 		if (++count == number)
 		{
-			add_buf(buffer, draw_line(ch, "{m-{M-", 0));
-			sprintf(buf, "\n\rHelp Keywords : %s\n\r", pHelp->keyword);
-			add_buf(buffer, buf);
-			add_buf(buffer, draw_line(ch, "{m-{M-", 0));
-			add_buf(buffer, "\n\r");
+			bprintln(buffer, draw_line(ch, "{m-{M-", 0));
+			bprintlnf(buffer, "Help Keywords : %s", pHelp->keyword);
+			bprintln(buffer, draw_line(ch, "{m-{M-", 0));
 			if (pHelp->text[0] == '.')
-				add_buf(buffer, pHelp->text + 1);
+				bprint(buffer, pHelp->text + 1);
 			else
-				add_buf(buffer, pHelp->text);
-			add_buf(buffer, draw_line(ch, "{m-{M-", 0));
-			add_buf(buffer, "\n\r");
+				bprint(buffer, pHelp->text);
+			bprintln(buffer, draw_line(ch, "{m-{M-", 0));
 			found = TRUE;
 		}
 		else
 		{
-			sprintf(buf, "%s, ", pHelp->keyword);
-			add_buf(related, buf);
+			bprintf(related, MXPTAG("Help '%s'") "%s" MXPTAG("/Help") ", ",
+					pHelp->keyword, pHelp->keyword);
 		}
 	}
 	if (list)
 	{
-		const char *text;
-		char buf[MIL];
-
-		text = str_dup(buf_string(buffer));
+		const char *text = str_dup(buf_string(buffer));
 		clear_buf(buffer);
-		sprintf(buf, "Help files that start with the letter '%s'.\n\r",
-				argall2);
-		add_buf(buffer, buf);
-		add_buf(buffer, draw_line(ch, "{m-{M-", 0));
-		add_buf(buffer, "\n\r");
-		add_buf(buffer, text);
-		add_buf(buffer, draw_line(ch, "{m-{M-", 0));
-		sprintf(buf, "\n\r%d total help files.\n\r", counter);
-		add_buf(buffer, buf);
+		bprintlnf(buffer, "Help files that start with the letter '%s'.",
+				  argall2);
+		bprintln(buffer, draw_line(ch, "{m-{M-", 0));
+		bprint(buffer, text);
+		bprintln(buffer, draw_line(ch, "{m-{M-", 0));
+		bprintlnf(buffer, "%d total help files.", counter);
 		free_string(text);
 	}
 
 	else if (!found)
 	{
-		sprintf(buf,
-				"No help found for %s. Try using just the first letter.\n\r",
-				nohelp);
-		add_buf(buffer, buf);
+		bprintlnf(buffer,
+				  "No help found for %s. Try using just the first letter.\n\r",
+				  nohelp);
 		sprintf(log_buf, "Missing Help: %s", nohelp);
 		wiznet(log_buf, ch, NULL, 0, 0, 0);
 	}
-	else if (related->string != NULL && related->string[0] != '\0')
+	else if (!IS_NULLSTR(related->string))
 	{
 		related->string[strlen(related->string) - 2] = '.';
 		related->string[strlen(related->string) - 1] = '\0';
-		sprintf(buf, "See Also : %s\n\r%s\n\r", buf_string(related),
-				draw_line(ch, "{m-{M-", 0));
-		add_buf(buffer, buf);
+		bprintlnf(buffer, "See Also : %s\n\r%s", buf_string(related),
+				  draw_line(ch, "{m-{M-", 0));
 	}
-	page_to_char(buf_string(buffer), ch);
+	sendpage(ch, buf_string(buffer));
 	free_buf(buffer);
 	free_buf(related);
 }
@@ -1934,15 +2095,15 @@
 
 	output = new_buf();
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 		argument = "summary";
 
 	/* this parts handles help a b so that it returns help 'a b' */
 	argall[0] = '\0';
-	while (argument[0] != '\0')
+	while (!IS_NULLSTR(argument))
 	{
 		argument = one_argument(argument, argone);
-		if (argall[0] != '\0')
+		if (!IS_NULLSTR(argall))
 			strcat(argall, " ");
 		strcat(argall, argone);
 	}
@@ -1958,21 +2119,20 @@
 		{
 			/* add seperator if found */
 			if (found)
-				add_buf(output,
-						"\n\r============================================================\n\r\n\r");
+				bprintln(output,
+						 "\n\r============================================================\n\r");
 			if (pHelp->level >= 0 && str_cmp(argall, "imotd"))
 			{
-				add_buf(output, pHelp->keyword);
-				add_buf(output, "\n\r");
+				bprintln(output, pHelp->keyword);
 			}
 
 			/*
 			 * Strip leading '.' to allow initial blanks.
 			 */
 			if (pHelp->text[0] == '.')
-				add_buf(output, pHelp->text + 1);
+				bprint(output, pHelp->text + 1);
 			else
-				add_buf(output, pHelp->text);
+				bprint(output, pHelp->text);
 			found = TRUE;
 			/* small hack :) */
 			if (ch->desc != NULL && ch->desc->connected != CON_PLAYING
@@ -1984,7 +2144,7 @@
 	if (!found)
 		chprintln(ch, "No help on that word.");
 	else
-		page_to_char(buf_string(output), ch);
+		sendpage(ch, buf_string(output));
 	free_buf(output);
 }
 
@@ -2010,23 +2170,24 @@
 	/*
 	 * Format it up.
 	 */
-	if (wch->pcdata->who_descr[0] != '\0' && wch->pcdata->who_descr != NULL)
+	if (!IS_NULLSTR(wch->pcdata->who_descr))
 		sprintf(block, "[%s] ",
-				stringf(ch, 14, ALIGN_CENTER, NULL, wch->pcdata->who_descr));
+				stringf(ch, 12, ALIGN_CENTER, NULL, wch->pcdata->who_descr));
 	else
 		sprintf(block,
 				"[" CTAG(_WLEVEL) "%3.3s " CTAG(_WRACE) "%4.4s " CTAG(_WCLASS)
 				"%3.3s{x] ", high_level_name(wch->level, FALSE),
 				wch->race->name, class_who(wch));
 
-	sprintf(buf, "%s%s%s%s%s%s%s%s%s%s%s%s\n\r", block,
+	sprintf(buf, "%s%s%s%s%s%s%s%s%s"
+			MXPTAG("Fwho '%s'") "%s" MXPTAG("/Fwho") "%s%s\n\r", block,
 			wch->incog_level >= LEVEL_HERO ? "(Incog) " : "",
 			wch->invis_level >= LEVEL_HERO ? "(Wizi) " : "",
 			IS_SET(wch->comm, COMM_AFK) ? "[AFK] " : "",
 			IS_QUESTOR(wch) ? "[Q] " : "",
 			ON_GQUEST(wch) ? "(GQuest) " : "", wch->war ? "(WAR) " :
 			"", IS_SET(wch->act, PLR_KILLER) ? "(KILLER) " : "",
-			IS_SET(wch->act, PLR_THIEF) ? "(THIEF) " : "", wch->name,
+			IS_SET(wch->act, PLR_THIEF) ? "(THIEF) " : "", wch->name, wch->name,
 			IS_NPC(wch) ? "" : wch->pcdata->title, format_clan(wch));
 	return (buf);
 }
@@ -2041,7 +2202,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "You must provide a name.");
 		return;
@@ -2065,7 +2226,7 @@
 		{
 			found = TRUE;
 
-			add_buf(output, format_who(ch, wch));
+			bprint(output, format_who(ch, wch));
 		}
 	}
 
@@ -2075,17 +2236,16 @@
 		return;
 	}
 
-	page_to_char(buf_string(output), ch);
+	sendpage(ch, buf_string(output));
 	free_buf(output);
 }
 
 CH_CMD(do_whowas)
 {
 	char arg[MIL];
-	char buf[MSL];
 	CHAR_DATA *victim;
 	bool fOld;
-	FILE *fp;
+	READ_DATA *fp;
 
 	one_argument(argument, arg);
 	if (IS_NULLSTR(arg))
@@ -2107,8 +2267,7 @@
 	victim->pcdata = new_pcdata();
 	pload_default(victim);
 	fOld = FALSE;
-	sprintf(buf, "%s%s", PLAYER_DIR, capitalize(arg));
-	if ((fp = file_open(buf, "r")) != NULL)
+	if ((fp = open_read("%s%s", PLAYER_DIR, capitalize(arg))) != NULL)
 	{
 		fOld = TRUE;
 
@@ -2117,22 +2276,22 @@
 			char letter;
 			char *word;
 
-			letter = fread_letter(fp);
+			letter = read_letter(fp);
 			if (letter == '*')
 			{
-				fread_to_eol(fp);
+				read_to_eol(fp);
 				continue;
 			}
 
 			if (letter != '#')
 			{
-				bug("do_whowas: # not found.", 0);
+				bug("do_whowas: # not found.");
 				break;
 			}
 
-			word = fread_word(fp);
+			word = read_word(fp);
 			if (!str_cmp(word, "PLAYER"))
-				fread_char(victim, fp);
+				read_char(victim, fp);
 			else if (!str_cmp(word, "PET"))
 				break;
 			else if (!str_cmp(word, "O"))
@@ -2142,10 +2301,9 @@
 			else
 				break;
 		}
+		close_read(fp);
 	}
 
-	file_close(fp);
-
 	if (!fOld)
 	{
 		chprintln(ch, "No player by that name exists.");
@@ -2177,12 +2335,11 @@
 CH_CMD(do_who)
 {
 	char buf[MAX_STRING_LENGTH];
-	char buf2[MAX_STRING_LENGTH];
 	BUFFER *output;
 	DESCRIPTOR_DATA *d;
 	int iClass;
-	RACE_DATA *iRace;
-	CLAN_DATA *iClan;
+	RACE_DATA *iRace = NULL;
+	CLAN_DATA *iClan = NULL;
 	int iLevelLower;
 	int iLevelUpper;
 	int nNumber;
@@ -2217,7 +2374,7 @@
 		char arg[MAX_STRING_LENGTH];
 
 		argument = one_argument(argument, arg);
-		if (arg[0] == '\0')
+		if (IS_NULLSTR(arg))
 			break;
 		else
 			searched = TRUE;
@@ -2296,8 +2453,8 @@
 
 	alloc_mem(charitems, struct s_charitem, ndesc);
 
-	if (ndesc > max_on)
-		max_on = ndesc;
+	if (ndesc > mud_info.max_online)
+		mud_info.max_online = ndesc;
 
 	/*
 	 * Now show matching chars.
@@ -2305,8 +2462,7 @@
 	nMatch = 0;
 	buf[0] = '\0';
 	output = new_buf();
-	add_buf(output, draw_line(ch, "{r-{R-", 0));
-	add_buf(output, "\n\r");
+	bprintln(output, draw_line(ch, "{r-{R-", 0));
 	for (d = descriptor_first; d != NULL; d = d->next)
 	{
 		/*
@@ -2362,43 +2518,44 @@
 	for (j1 = 0; j1 < nMatch; j1++)
 	{
 		wch = charitems[j1].pch;
-		add_buf(output, format_who(ch, wch));
+		bprint(output, format_who(ch, wch));
 		if (j1 == (immcount - imminvis - 1) && j1 != (nMatch - 1)
 			&& IS_IMMORTAL(wch))
 		{
-			add_buf(output, draw_line(ch, "{r-{R-", 0));
-			add_buf(output, "\n\r");
+			bprintln(output, draw_line(ch, "{r-{R-", 0));
 		}
 	}
 
 	free_mem(charitems);
 
-	add_buf(output, draw_line(ch, "{r-{R-", 0));
-	add_buf(output, "\n\r");
+	bprintln(output, draw_line(ch, "{r-{R-", 0));
 
 	if (searched)
 	{
-		sprintf(buf2, "{WMatches found: {R%d{x\n\r", nMatch);
-		add_buf(output, buf2);
+		bprintlnf(output, "{WMatches found: {R%d{x", nMatch);
 	}
 	else if (nMatch < (totalcount - imminvis))
 	{
-		sprintf(buf2,
-				"{WPlayers found: {R%d{W  Most since boot: {R%d{W  Invisible: {R%d{x\n\r",
-				nMatch, max_on, (totalcount - nMatch - imminvis));
-		add_buf(output, buf2);
+		bprintlnf(output,
+				  "{WPlayers found: {R%d{W  Most on ever: {R%d{W  Invisible: {R%d{x",
+				  nMatch, mud_info.max_online,
+				  (totalcount - nMatch - imminvis));
 	}
 	else
 	{
-		sprintf(buf2, "{WPlayers found: {R%d{W  Most since boot: {R%d{x\n\r",
-				totalcount - imminvis, max_on);
-		add_buf(output, buf2);
+		bprintlnf(output, "{WPlayers found: {R%d{W  Most on ever: {R%d{x",
+				  totalcount - imminvis, mud_info.max_online);
 	}
 
 	if (!ON_GQUEST(ch) && gquest_info.minlevel < ch->level &&
 		gquest_info.maxlevel > ch->level)
-		add_buf(output, "There is a Global Quest running you can join.\n\r");
-	page_to_char(buf_string(output), ch);
+		bprintln(output, "{WThere is a Global Quest running you can join.{x");
+	if (crs_info.timer > -1 && crs_info.status != CRS_NONE)
+	{
+		bprintlnf(output, "{W%s{x", crs_sprintf(TRUE, FALSE));
+	}
+
+	sendpage(ch, buf_string(output));
 	free_buf(output);
 	free_mem(rgfClass);
 	return;
@@ -2415,20 +2572,22 @@
 		if (d->connected == CON_PLAYING && can_see(ch, d->character))
 			count++;
 
-	max_on = UMAX(count, max_on);
+	mud_info.max_online = UMAX(count, mud_info.max_online);
 
-	if (max_on == count)
-		chprintlnf(ch,
-				   "There are %d characters on, the most so far today.", count);
+	if (mud_info.max_online == count)
+		chprintlnf(ch, "There are %d characters on, the most ever.", count);
 	else
 		chprintlnf(ch,
-				   "There are %d characters on, the most on today was %d.",
-				   count, max_on);
+				   "There are %d characters on, the most on ever was %d.",
+				   count, mud_info.max_online);
 }
 
 CH_CMD(do_inventory)
 {
-	chprintln(ch, "You are carrying:");
+	chprintlnf(ch,
+			   "{YYou are carrying {W%d/%d{Y items with {W%ld/%d{Y weight:{x",
+			   ch->carry_number, can_carry_n(ch), get_carry_weight(ch) / 10,
+			   can_carry_w(ch) / 10);
 	show_list_to_char(ch->first_carrying, ch, TRUE, TRUE);
 	return;
 }
@@ -2442,10 +2601,9 @@
 	for (iWear = 0; iWear < MAX_WEAR; iWear++)
 	{
 		chprint(ch, where_name[iWear]);
-		if ((obj = get_eq_char(ch, iWear)) == NULL)
+		if ((obj = get_eq_char(ch, (wloc_t) iWear)) == NULL)
 		{
 			chprintln(ch, "nothing.");
-			continue;
 		}
 		else if (can_see_obj(ch, obj))
 		{
@@ -2471,7 +2629,7 @@
 
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		chprintln(ch, "Compare what to what?");
 		return;
@@ -2483,7 +2641,7 @@
 		return;
 	}
 
-	if (arg2[0] == '\0')
+	if (IS_NULLSTR(arg2))
 	{
 		for (obj2 = ch->first_carrying; obj2 != NULL; obj2 = obj2->next_content)
 		{
@@ -2562,6 +2720,8 @@
 CH_CMD(do_credits)
 {
 	do_function(ch, &do_oldhelp, "diku");
+	do_function(ch, &do_oldhelp, "ROM");
+	do_function(ch, &do_oldhelp, "1stMUD");
 	return;
 }
 
@@ -2574,8 +2734,24 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
+		chprintlnf(ch, "You are in zone  : %s", ch->in_room->area->name);
+		if (!IS_NULLSTR(ch->in_room->area->lvl_comment))
+			chprintlnf(ch, "Recomended Levels: [%-7s]",
+					   ch->in_room->area->lvl_comment);
+		else
+			chprintlnf(ch, "Recomended Levels: [%03d %03d]",
+					   ch->in_room->area->min_level,
+					   ch->in_room->area->max_level);
+
+		chprintlnf(ch, "Author           : [%-7s]", ch->in_room->area->credits);
+		if (IS_IMMORTAL(ch))
+		{
+			chprintlnf(ch, "Vnum Range       : %ld to %ld",
+					   ch->in_room->area->min_vnum,
+					   ch->in_room->area->max_vnum);
+		}
 		chprintln(ch, "Players near you:");
 		found = FALSE;
 		for (d = descriptor_first; d; d = d->next)
@@ -2629,7 +2805,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Consider killing whom?");
 		return;
@@ -2674,7 +2850,7 @@
 
 	if (IS_NPC(ch))
 	{
-		bug("Set_title: NPC.", 0);
+		bug("Set_title: NPC.");
 		return;
 	}
 
@@ -2689,8 +2865,7 @@
 		strcpy(buf, title);
 	}
 
-	free_string(ch->pcdata->title);
-	ch->pcdata->title = str_dup(buf);
+	replace_string(ch->pcdata->title, buf);
 	return;
 }
 
@@ -2701,7 +2876,7 @@
 	if (IS_NPC(ch))
 		return;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Change your title to what?");
 		return;
@@ -2721,7 +2896,7 @@
 {
 	char buf[MAX_STRING_LENGTH];
 
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		buf[0] = '\0';
 		smash_tilde(argument);
@@ -2731,7 +2906,7 @@
 			int len;
 			bool found = FALSE;
 
-			if (ch->description == NULL || ch->description[0] == '\0')
+			if (IS_NULLSTR(ch->description))
 			{
 				chprintln(ch, "No lines left to remove.");
 				return;
@@ -2752,8 +2927,7 @@
 					else		/* found the second one */
 					{
 						buf[len + 1] = '\0';
-						free_string(ch->description);
-						ch->description = str_dup(buf);
+						replace_string(ch->description, buf);
 						chprintln(ch, "Your description is:");
 						chprint(ch, ch->description ?
 								ch->description : "(None).\n\r");
@@ -2762,8 +2936,7 @@
 				}
 			}
 			buf[0] = '\0';
-			free_string(ch->description);
-			ch->description = str_dup(buf);
+			replace_string(ch->description, buf);
 			chprintln(ch, "Description cleared.");
 			return;
 		}
@@ -2784,8 +2957,7 @@
 
 		strcat(buf, argument);
 		strcat(buf, "\n\r");
-		free_string(ch->description);
-		ch->description = str_dup(buf);
+		replace_string(ch->description, buf);
 	}
 
 	chprintln(ch, "Your description is:");
@@ -2819,7 +2991,7 @@
 	if (IS_NPC(ch))
 		return;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		int col;
 
@@ -2925,7 +3097,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 		wimpy = ch->max_hit / 5;
 	else
 		wimpy = atoi(arg);
@@ -3001,7 +3173,7 @@
 	}
 	*pArg = '\0';
 
-	if (arg1[0] == '\0' || arg2[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
 	{
 		chprintln(ch, "Syntax: password <old> <new>.");
 		return;
@@ -3033,8 +3205,7 @@
 		}
 	}
 
-	free_string(ch->pcdata->pwd);
-	ch->pcdata->pwd = str_dup(pwdnew);
+	replace_string(ch->pcdata->pwd, pwdnew);
 	save_char_obj(ch);
 	chprintln(ch, "Ok.");
 	return;
diff -ur -x config -x o -x rom src/act_move.c new/act_move.c
--- src/act_move.c	Tue May 27 02:46:35 2003
+++ new/act_move.c	Sun Aug 31 19:23:20 2003
@@ -22,17 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
 #include "merc.h"
 #include "interp.h"
 
@@ -51,8 +44,8 @@
 /*
  * Local functions.
  */
-int find_door args((CHAR_DATA * ch, char *arg));
-bool has_key args((CHAR_DATA * ch, vnum_t key));
+PROTOTYPE(int find_door, (CHAR_DATA *, char *));
+PROTOTYPE(bool has_key, (CHAR_DATA *, vnum_t));
 
 void move_char(CHAR_DATA * ch, int door, bool follow)
 {
@@ -64,7 +57,7 @@
 
 	if (door < 0 || door > 5)
 	{
-		bug("Do_move: bad door %d.", door);
+		bugf("Do_move: bad door %d.", door);
 		return;
 	}
 
@@ -193,6 +186,9 @@
 		ch->move -= move;
 	}
 
+	if (IS_VALID_STANCE(GET_STANCE(ch, STANCE_CURRENT)))
+		do_function(ch, &do_stance, "");
+
 	if (!IS_AFFECTED(ch, AFF_SNEAK) && ch->invis_level < LEVEL_HERO)
 		act("$n leaves $T.", ch, NULL, dir_name[door], TO_ROOM);
 
@@ -368,7 +364,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Open what?");
 		return;
@@ -479,7 +475,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Close what?");
 		return;
@@ -589,7 +585,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Lock what?");
 		return;
@@ -722,7 +718,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Unlock what?");
 		return;
@@ -856,7 +852,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Pick what?");
 		return;
@@ -1002,7 +998,7 @@
 {
 	OBJ_DATA *obj = NULL;
 
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		if (ch->position == POS_FIGHTING)
 		{
@@ -1104,6 +1100,8 @@
 	case POS_FIGHTING:
 		chprintln(ch, "You are already fighting!");
 		break;
+	default:
+		break;
 	}
 
 	return;
@@ -1120,7 +1118,7 @@
 	}
 
 	/* okay, now that we know we can rest, find an object to rest on */
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		obj = get_obj_list(ch, argument, ch->in_room->first_content);
 		if (obj == NULL)
@@ -1242,6 +1240,8 @@
 		}
 		ch->position = POS_RESTING;
 		break;
+	default:
+		break;
 	}
 
 	return;
@@ -1258,7 +1258,7 @@
 	}
 
 	/* okay, now that we know we can sit, find an object to sit on */
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		obj = get_obj_list(ch, argument, ch->in_room->first_content);
 		if (obj == NULL)
@@ -1368,6 +1368,8 @@
 		}
 		ch->position = POS_SITTING;
 		break;
+	default:
+		break;
 	}
 	return;
 }
@@ -1385,7 +1387,7 @@
 	case POS_RESTING:
 	case POS_SITTING:
 	case POS_STANDING:
-		if (argument[0] == '\0' && ch->on == NULL)
+		if (IS_NULLSTR(argument) && ch->on == NULL)
 		{
 			chprintln(ch, "You go to sleep.");
 			act("$n goes to sleep.", ch, NULL, NULL, TO_ROOM);
@@ -1393,7 +1395,7 @@
 		}
 		else					/* find an object and sleep on it */
 		{
-			if (argument[0] == '\0')
+			if (IS_NULLSTR(argument))
 				obj = ch->on;
 			else
 				obj = get_obj_list(ch, argument, ch->in_room->first_content);
@@ -1445,6 +1447,8 @@
 	case POS_FIGHTING:
 		chprintln(ch, "You are already fighting!");
 		break;
+	default:
+		break;
 	}
 
 	return;
@@ -1456,7 +1460,7 @@
 	CHAR_DATA *victim;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		do_function(ch, &do_stand, "");
 		return;
@@ -1647,7 +1651,7 @@
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintlnf(ch, "You have %d training sessions.", ch->train);
 		argument = "foo";
diff -ur -x config -x o -x rom src/act_obj.c new/act_obj.c
--- src/act_obj.c	Tue May 27 02:46:35 2003
+++ new/act_obj.c	Sun Aug 31 19:23:20 2003
@@ -22,17 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "interp.h"
 
@@ -41,10 +34,10 @@
  */
 #define CD CHAR_DATA
 #define OD OBJ_DATA
-bool remove_obj args((CHAR_DATA * ch, int iWear, bool fReplace));
-CD *find_keeper args((CHAR_DATA * ch));
-int get_cost args((CHAR_DATA * keeper, OBJ_DATA * obj, bool fBuy));
-OD *get_obj_keeper args((CHAR_DATA * ch, CHAR_DATA * keeper, char *argument));
+PROTOTYPE(bool remove_obj, (CHAR_DATA *, int, bool));
+PROTOTYPE(CD * find_keeper, (CHAR_DATA *));
+PROTOTYPE(int get_cost, (CHAR_DATA *, OBJ_DATA *, bool));
+PROTOTYPE(OD * get_obj_keeper, (CHAR_DATA *, CHAR_DATA *, char *));
 
 #undef OD
 #undef	CD
@@ -211,13 +204,13 @@
 		argument = one_argument(argument, arg2);
 
 	/* Get type. */
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		chprintln(ch, "Get what?");
 		return;
 	}
 
-	if (arg2[0] == '\0')
+	if (IS_NULLSTR(arg2))
 	{
 		if (str_cmp(arg1, "all") && str_prefix("all.", arg1))
 		{
@@ -358,7 +351,7 @@
 	if (!str_cmp(arg2, "in") || !str_cmp(arg2, "on"))
 		argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
 	{
 		chprintln(ch, "Put what in what?");
 		return;
@@ -506,7 +499,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Drop what?");
 		return;
@@ -677,7 +670,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
 	{
 		chprintln(ch, "Give what to whom?");
 		return;
@@ -701,7 +694,7 @@
 		silver = str_cmp(arg2, "gold");
 
 		argument = one_argument(argument, arg2);
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			chprintln(ch, "Give what to whom?");
 			return;
@@ -868,7 +861,7 @@
 	int percent, skill;
 
 	/* find out what */
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Envenom what item?");
 		return;
@@ -950,7 +943,7 @@
 			af.type = gsn_poison;
 			af.level = ch->level * percent / 100;
 			af.duration = ch->level / 2 * percent / 100;
-			af.location = 0;
+			af.location = APPLY_NONE;
 			af.modifier = 0;
 			af.bitvector = WEAPON_POISON;
 			affect_to_obj(obj, &af);
@@ -984,7 +977,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Fill what?");
 		return;
@@ -1051,7 +1044,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0' || argument[0] == '\0')
+	if (IS_NULLSTR(arg) || IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Pour what into what?");
 		return;
@@ -1177,7 +1170,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		for (obj = ch->in_room->first_content; obj; obj = obj->next_content)
 		{
@@ -1215,7 +1208,7 @@
 	case ITEM_FOUNTAIN:
 		if ((liquid = obj->value[2]) < 0)
 		{
-			bug("Do_drink: bad liquid number %d.", liquid);
+			bugf("Do_drink: bad liquid number %d.", liquid);
 			liquid = obj->value[2] = 0;
 		}
 		amount = liq_table[liquid].liq_affect[4] * 3;
@@ -1230,7 +1223,7 @@
 
 		if ((liquid = obj->value[2]) < 0)
 		{
-			bug("Do_drink: bad liquid number %d.", liquid);
+			bugf("Do_drink: bad liquid number %d.", liquid);
 			liquid = obj->value[2] = 0;
 		}
 
@@ -1293,7 +1286,7 @@
 	OBJ_DATA *obj;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Eat what?");
 		return;
@@ -1373,7 +1366,7 @@
 /*
  * Remove an object.
  */
-bool remove_obj(CHAR_DATA * ch, int iWear, bool fReplace)
+bool remove_obj(CHAR_DATA * ch, wloc_t iWear, bool fReplace)
 {
 	OBJ_DATA *obj;
 
@@ -1445,7 +1438,7 @@
 			return;
 		}
 
-		bug("Wear_obj: no free finger.", 0);
+		bug("Wear_obj: no free finger.");
 		chprintln(ch, "You already wear two rings.");
 		return;
 	}
@@ -1474,7 +1467,7 @@
 			return;
 		}
 
-		bug("Wear_obj: no free neck.", 0);
+		bug("Wear_obj: no free neck.");
 		chprintln(ch, "You already wear two neck items.");
 		return;
 	}
@@ -1583,7 +1576,7 @@
 			return;
 		}
 
-		bug("Wear_obj: no free wrist.", 0);
+		bug("Wear_obj: no free wrist.");
 		chprintln(ch, "You already wear two wrist items.");
 		return;
 	}
@@ -1710,7 +1703,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Wear, wield, or hold what?");
 		return;
@@ -1749,7 +1742,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Remove what?");
 		return;
@@ -1792,7 +1785,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0' || !str_cmp(arg, ch->name))
+	if (IS_NULLSTR(arg) || !str_cmp(arg, ch->name))
 	{
 		act("$n offers $mself to $g, who graciously declines.", ch,
 			NULL, NULL, TO_ROOM);
@@ -1801,6 +1794,17 @@
 		return;
 	}
 
+	if (!str_cmp(arg, "all"))
+	{
+		OBJ_DATA *next;
+
+		for (obj = ch->in_room->first_content; obj; obj = next)
+		{
+			next = obj->next_content;
+			do_sacrifice(ch, obj->name);
+		}
+		return;
+	}
 	obj = get_obj_list(ch, arg, ch->in_room->first_content);
 	if (obj == NULL)
 	{
@@ -1881,7 +1885,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Quaff what?");
 		return;
@@ -1954,7 +1958,7 @@
 	}
 
 	obj = NULL;
-	if (arg2[0] == '\0')
+	if (IS_NULLSTR(arg2))
 	{
 		victim = ch;
 	}
@@ -2011,7 +2015,7 @@
 	if ((sn = staff->value[3]) < 0 || sn >= maxSkill ||
 		skill_table[sn].spell_fun == 0)
 	{
-		bug("Do_brandish: bad sn %d.", sn);
+		bugf("Do_brandish: bad sn %d.", sn);
 		return;
 	}
 
@@ -2037,7 +2041,7 @@
 				switch (skill_table[sn].target)
 				{
 				default:
-					bug("Do_brandish: bad target for sn %d.", sn);
+					bugf("Do_brandish: bad target for sn %d.", sn);
 					return;
 
 				case TAR_IGNORE:
@@ -2084,7 +2088,7 @@
 	OBJ_DATA *obj;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0' && ch->fighting == NULL)
+	if (IS_NULLSTR(arg) && ch->fighting == NULL)
 	{
 		chprintln(ch, "Zap whom or what?");
 		return;
@@ -2103,7 +2107,7 @@
 	}
 
 	obj = NULL;
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		if (ch->fighting != NULL)
 		{
@@ -2179,7 +2183,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
 	{
 		chprintln(ch, "Steal what from whom?");
 		return;
@@ -2503,7 +2507,7 @@
 	char buf[MAX_STRING_LENGTH];
 	int cost, roll;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Buy what?");
 		return;
@@ -2530,7 +2534,7 @@
 			pRoomIndexNext = get_room_index(ch->in_room->vnum + 1);
 		if (pRoomIndexNext == NULL)
 		{
-			bug("Do_buy: bad pet shop at vnum %d.", ch->in_room->vnum);
+			bugf("Do_buy: bad pet shop at vnum %ld.", ch->in_room->vnum);
 			chprintln(ch, "Sorry, you can't buy that here.");
 			return;
 		}
@@ -2583,17 +2587,15 @@
 		pet->comm = COMM_NOTELL | COMM_NOSHOUT | COMM_NOCHANNELS;
 
 		argument = one_argument(argument, arg);
-		if (arg[0] != '\0')
+		if (!IS_NULLSTR(arg))
 		{
 			sprintf(buf, "%s %s", pet->name, arg);
-			free_string(pet->name);
-			pet->name = str_dup(buf);
+			replace_string(pet->name, buf);
 		}
 
 		sprintf(buf, "%sA neck tag says 'I belong to %s'.\n\r",
 				pet->description, ch->name);
-		free_string(pet->description);
-		pet->description = str_dup(buf);
+		replace_string(pet->description, buf);
 
 		char_to_room(pet, ch->in_room);
 		add_follower(pet, ch);
@@ -2750,7 +2752,7 @@
 
 		if (pRoomIndexNext == NULL)
 		{
-			bug("Do_list: bad pet shop at vnum %d.", ch->in_room->vnum);
+			bugf("Do_list: bad pet shop at vnum %ld.", ch->in_room->vnum);
 			chprintln(ch, "You can't do that here.");
 			return;
 		}
@@ -2788,9 +2790,14 @@
 		found = FALSE;
 		for (obj = keeper->first_carrying; obj; obj = obj->next_content)
 		{
+			int i = 0;
+			const char *p = obj->name;
+
+			for (; *p && !isspace(*p); p++, i++)
+				;
 			if (obj->wear_loc == WEAR_NONE && can_see_obj(ch, obj) &&
 				(cost = get_cost(keeper, obj, TRUE)) > 0 &&
-				(arg[0] == '\0' || is_name(arg, obj->name)))
+				(IS_NULLSTR(arg) || is_name(arg, obj->name)))
 			{
 				if (!found)
 				{
@@ -2799,8 +2806,10 @@
 				}
 
 				if (IS_OBJ_STAT(obj, ITEM_INVENTORY))
-					chprintlnf(ch, "[%2d %5d -- ] %s",
-							   obj->level, cost, obj->short_descr);
+					chprintlnf(ch, "[%2d %5d -- ] "
+							   MXPTAG("List '%.*s' '%s'") "%s" MXPTAG("/List"),
+							   obj->level, cost, i, obj->name, obj->short_descr,
+							   obj->short_descr);
 				else
 				{
 					count = 1;
@@ -2814,8 +2823,10 @@
 						obj = obj->next_content;
 						count++;
 					}
-					chprintlnf(ch, "[%2d %5d %2d ] %s",
-							   obj->level, cost, count, obj->short_descr);
+					chprintlnf(ch, "[%2d %5d %2d ] "
+							   MXPTAG("List '%.*s' '%s'") "%s" MXPTAG("/List"),
+							   obj->level, cost, count, i, obj->name,
+							   obj->short_descr, obj->short_descr);
 				}
 			}
 		}
@@ -2836,7 +2847,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Sell what?");
 		return;
@@ -2933,7 +2944,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Value what?");
 		return;
@@ -2982,7 +2993,7 @@
 {
 	OBJ_DATA *obj;
 
-	if (argument[0] == '\0')	/* empty */
+	if (IS_NULLSTR(argument))	/* empty */
 	{
 		chprintln(ch, "Wear which weapon in your off-hand?");
 		return;
@@ -3072,7 +3083,7 @@
 
 	if (obj == NULL)
 	{
-		bug("donate_object: NULL obj", 0);
+		bug("donate_object: NULL obj");
 		return;
 	}
 
@@ -3087,7 +3098,7 @@
 
 	if (!(container = get_donation_pit()))
 	{
-		bug("donate_object: no donation pit!", 0);
+		bug("donate_object: no donation pit!");
 		extract_obj(obj);
 	}
 	else
@@ -3191,7 +3202,7 @@
 void save_donation_pit(void)
 {
 	OBJ_DATA *pit;
-	FILE_DATA *fp;
+	WRITE_DATA *fp;
 
 	for (pit = object_first; pit; pit = pit->next)
 	{
@@ -3202,24 +3213,24 @@
 	if (!pit)
 		return;
 
-	if ((fp = fopen_temp(PIT_FILE)) != NULL)
+	if ((fp = open_write(PIT_FILE)) != NULL)
 	{
 		if (pit->first_content)
-			fwrite_obj(NULL, pit->first_content, fp->file, 0, "P");
-		fprintf(fp->file, "#END\n");
-		fflush(fp->file);
-		fclose_temp(fp);
+			fwrite_obj(NULL, pit->first_content, fp->stream, 0, "P");
+		fprintf(fp->stream, "#END\n");
+		fflush(fp->stream);
+		close_write(fp);
 	}
 }
 
 void load_donation_pit(void)
 {
-	FILE *fp;
+	READ_DATA *fp;
 	int count;
 
-	if ((fp = file_open(PIT_FILE, "r")) == NULL)
+	if ((fp = open_read(PIT_FILE)) == NULL)
 	{
-		bug("load_donation_pit: " PIT_FILE " not found", 0);
+		bug("load_donation_pit: " PIT_FILE " not found");
 	}
 	else
 	{
@@ -3230,23 +3241,23 @@
 			char letter;
 			char *word;
 
-			letter = fread_letter(fp);
+			letter = read_letter(fp);
 			if (letter == '*')
 			{
-				fread_to_eol(fp);
+				read_to_eol(fp);
 				continue;
 			}
 
 			if (letter != '#')
 			{
-				bug("load_donation_pit: # not found.", 0);
+				bug("load_donation_pit: # not found.");
 				break;
 			}
 
-			word = fread_word(fp);
+			word = read_word(fp);
 			if ((!str_cmp(word, "P")))
 			{
-				fread_obj(NULL, fp, TRUE);
+				read_obj(NULL, fp, TRUE);
 				count++;
 				if (count >= 100)
 					break;
@@ -3255,13 +3266,12 @@
 				break;
 			else
 			{
-				bug("load_donation_pit: bad section.", 0);
+				bug("load_donation_pit: bad section.");
 				break;
 			}
 		}
+		close_read(fp);
 	}
-
-	file_close(fp);
 
 	return;
 }
diff -ur -x config -x o -x rom src/act_wiz.c new/act_wiz.c
--- src/act_wiz.c	Tue May 27 02:46:35 2003
+++ new/act_wiz.c	Sun Aug 31 19:23:20 2003
@@ -22,37 +22,24 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 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"
+#include "tablesave.h"
+#include "signals.h"
 
 /*
  * Local functions.
  */
-ROOM_INDEX_DATA *find_location args((CHAR_DATA * ch, const char *arg));
+PROTOTYPE(ROOM_INDEX_DATA * find_location, (CHAR_DATA *, const char *));
 
 CH_CMD(do_wiznet)
 {
@@ -63,7 +50,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, stringf
 				  (ch, 0, ALIGN_CENTER, "-",
@@ -135,7 +122,7 @@
 	}
 	flag = wiznet_lookup(arg);
 
-	if (flag == 0 || get_trust(ch) < wiznet_table[flag].level)
+	if (flag == -1 || get_trust(ch) < wiznet_table[flag].level)
 	{
 		chprintln(ch, "No such option.");
 		return;
@@ -148,10 +135,27 @@
 					   CTAG(_WIZNET) " on wiznet.{x", wiznet_table[flag].name));
 }
 
-void wiznet(char *string, CHAR_DATA * ch, OBJ_DATA * obj, flag_t flag,
-			flag_t flag_skip, int min_level)
+void new_wiznet(CHAR_DATA * ch, OBJ_DATA * obj, flag_t flag,
+				flag_t flag_skip, int min_level, const char *format, ...)
 {
 	DESCRIPTOR_DATA *d;
+	va_list args;
+	char string[MSL * 2];
+	int i;
+	const char *chan;
+
+	if (IS_NULLSTR(format))
+		return;
+
+	va_start(args, format);
+	vsnprintf(string, sizeof(string), format, args);
+	va_end(args);
+
+	for (i = 0; wiznet_table[i].name != NULL; i++)
+		if (wiznet_table[i].flag == flag)
+			break;
+
+	chan = wiznet_table[i].name == NULL ? "all" : wiznet_table[i].name;
 
 	for (d = descriptor_first; d != NULL; d = d->next)
 	{
@@ -164,7 +168,13 @@
 			&& get_trust(d->character) >= min_level && d->character != ch)
 		{
 			if (IS_SET(d->character->wiznet, WIZ_PREFIX))
-				chprint(d->character, CTAG(_WIZNET) "--> ");
+				d_printf(d, CTAG(_WIZNET) "-%s-%s-> ", str_time(-1,
+																GET_TZONE
+																(d->character),
+																"%I:%M:%S"),
+						 chan);
+			else
+				d_print(d, CTAG(_WIZNET), 0);
 			act_new(string, d->character, obj, ch, TO_CHAR, POS_DEAD);
 		}
 	}
@@ -181,7 +191,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
 	{
 		chprintln(ch, "Syntax: guild <char> <cln name>");
 		return;
@@ -302,7 +312,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Nochannel whom?");
 		return;
@@ -353,7 +363,7 @@
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Emote what?");
 		return;
@@ -437,7 +447,7 @@
 	{
 		smash_tilde(argument);
 
-		if (argument[0] == '\0')
+		if (IS_NULLSTR(argument))
 		{
 			chprintlnf(ch, "Your poofin is %s", ch->pcdata->bamfin);
 			return;
@@ -449,8 +459,7 @@
 			return;
 		}
 
-		free_string(ch->pcdata->bamfin);
-		ch->pcdata->bamfin = str_dup(argument);
+		replace_string(ch->pcdata->bamfin, argument);
 
 		chprintlnf(ch, "Your poofin is now %s", ch->pcdata->bamfin);
 	}
@@ -464,7 +473,7 @@
 	{
 		smash_tilde(argument);
 
-		if (argument[0] == '\0')
+		if (IS_NULLSTR(argument))
 		{
 			chprintlnf(ch, "Your poofout is %s", ch->pcdata->bamfout);
 			return;
@@ -476,8 +485,7 @@
 			return;
 		}
 
-		free_string(ch->pcdata->bamfout);
-		ch->pcdata->bamfout = str_dup(argument);
+		replace_string(ch->pcdata->bamfout, argument);
 
 		chprintlnf(ch, "Your poofout is now %s", ch->pcdata->bamfout);
 	}
@@ -490,7 +498,7 @@
 	CHAR_DATA *victim;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Deny whom?");
 		return;
@@ -533,7 +541,7 @@
 	CHAR_DATA *victim;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Disconnect whom?");
 		return;
@@ -577,7 +585,7 @@
 		}
 	}
 
-	bug("Do_disconnect: desc not found.", 0);
+	bug("Do_disconnect: desc not found.");
 	chprintln(ch, "Descriptor not found!");
 	return;
 }
@@ -591,7 +599,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
 	{
 		chprintln(ch, "Syntax: pardon <character> <killer|thief>.");
 		return;
@@ -639,7 +647,7 @@
 {
 	DESCRIPTOR_DATA *d;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Global echo what?");
 		return;
@@ -662,7 +670,7 @@
 {
 	DESCRIPTOR_DATA *d;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Local echo what?");
 
@@ -686,7 +694,7 @@
 {
 	DESCRIPTOR_DATA *d;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Zone echo what?");
 		return;
@@ -712,7 +720,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (argument[0] == '\0' || arg[0] == '\0')
+	if (IS_NULLSTR(argument) || IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Personal echo what?");
 		return;
@@ -760,7 +768,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		chprintln(ch, "Transfer whom (and where)?");
 		return;
@@ -784,7 +792,7 @@
 	/*
 	 * Thanks to Grodyn for the optional location parameter.
 	 */
-	if (arg2[0] == '\0')
+	if (IS_NULLSTR(arg2))
 	{
 		location = ch->in_room;
 	}
@@ -838,7 +846,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0' || argument[0] == '\0')
+	if (IS_NULLSTR(arg) || IS_NULLSTR(argument))
 	{
 		chprintln(ch, "At where what?");
 		return;
@@ -887,7 +895,7 @@
 	CHAR_DATA *rch;
 	int count = 0;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Goto where?");
 		return;
@@ -917,7 +925,7 @@
 	{
 		if (get_trust(rch) >= ch->invis_level)
 		{
-			if (ch->pcdata != NULL && ch->pcdata->bamfout[0] != '\0')
+			if (ch->pcdata != NULL && !IS_NULLSTR(ch->pcdata->bamfout))
 				act("$t", ch, ch->pcdata->bamfout, rch, TO_VICT);
 			else
 				act("$n leaves in a swirling mist.", ch, NULL, rch, TO_VICT);
@@ -931,7 +939,7 @@
 	{
 		if (get_trust(rch) >= ch->invis_level)
 		{
-			if (ch->pcdata != NULL && ch->pcdata->bamfin[0] != '\0')
+			if (ch->pcdata != NULL && !IS_NULLSTR(ch->pcdata->bamfin))
 				act("$t", ch, ch->pcdata->bamfin, rch, TO_VICT);
 			else
 				act("$n appears in a swirling mist.", ch, NULL, rch, TO_VICT);
@@ -947,7 +955,7 @@
 	ROOM_INDEX_DATA *location;
 	CHAR_DATA *rch;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Goto where?");
 		return;
@@ -972,7 +980,7 @@
 	{
 		if (get_trust(rch) >= ch->invis_level)
 		{
-			if (ch->pcdata != NULL && ch->pcdata->bamfout[0] != '\0')
+			if (ch->pcdata != NULL && !IS_NULLSTR(ch->pcdata->bamfout))
 				act("$t", ch, ch->pcdata->bamfout, rch, TO_VICT);
 			else
 				act("$n leaves in a swirling mist.", ch, NULL, rch, TO_VICT);
@@ -986,7 +994,7 @@
 	{
 		if (get_trust(rch) >= ch->invis_level)
 		{
-			if (ch->pcdata != NULL && ch->pcdata->bamfin[0] != '\0')
+			if (ch->pcdata != NULL && !IS_NULLSTR(ch->pcdata->bamfin))
 				act("$t", ch, ch->pcdata->bamfin, rch, TO_VICT);
 			else
 				act("$n appears in a swirling mist.", ch, NULL, rch, TO_VICT);
@@ -999,7 +1007,7 @@
 
 /* RT to replace the 3 stat commands */
 
-CH_CMD(do_stat)
+CH_CMD(do_old_stat)
 {
 	char arg[MAX_INPUT_LENGTH];
 	const char *string;
@@ -1008,7 +1016,7 @@
 	CHAR_DATA *victim;
 
 	string = one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Syntax:");
 		chprintln(ch, "  stat <name>");
@@ -1072,7 +1080,7 @@
 	int door;
 
 	one_argument(argument, arg);
-	location = (arg[0] == '\0') ? ch->in_room : find_location(ch, arg);
+	location = (IS_NULLSTR(arg)) ? ch->in_room : find_location(ch, arg);
 	if (location == NULL)
 	{
 		chprintln(ch, "No such location.");
@@ -1162,7 +1170,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Stat what?");
 		return;
@@ -1461,7 +1469,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Stat whom?");
 		return;
@@ -1478,10 +1486,9 @@
 	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,
+			   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))
@@ -1605,17 +1612,30 @@
 
 	chprintf(ch, "Short description: %s\n\rLong  description: %s",
 			 victim->short_descr,
-			 victim->long_descr[0] != '\0' ? victim->long_descr : "(none)\n\r");
+			 !IS_NULLSTR(victim->long_descr) ? 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)
+	if (victim->desc != NULL)
 	{
-		chprintlnf(ch, "Descriptor Flags: %s",
-				   flag_string(desc_flags, victim->desc->d_flags));
+		if (victim->desc->d_flags != 0)
+			chprintlnf(ch, "Descriptor Flags: %s",
+					   flag_string(desc_flags, victim->desc->d_flags));
+		if (!IS_NULLSTR(victim->desc->ttype))
+			chprintlnf(ch, "Terminal: %s", victim->desc->ttype);
+		if (victim->desc->bytes_normal != 0)
+			chprintlnf(ch, "Bytes Normal: %ld", victim->desc->bytes_normal);
+#if !defined(NO_MCCP)
+		if (victim->desc->out_compress && victim->desc->bytes_compressed != 0)
+			chprintlnf(ch, "Bytes Compressed: %ld",
+					   victim->desc->bytes_compressed);
+		if (victim->desc->mccp_version != 0)
+			chprintlnf(ch, "MCCP version: %d", victim->desc->mccp_version);
+#endif
 	}
 	if (!IS_NPC(victim) && IS_SET(victim->act, PLR_QUESTOR))
 	{
@@ -1684,7 +1704,7 @@
 
 	string = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Syntax:");
 		chprintln(ch, "  vnum obj <name>");
@@ -1725,7 +1745,7 @@
 	bool found;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Find whom?");
 		return;
@@ -1771,7 +1791,7 @@
 	bool found;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Find what?");
 		return;
@@ -1809,7 +1829,6 @@
 
 CH_CMD(do_owhere)
 {
-	char buf[MAX_INPUT_LENGTH];
 	BUFFER *buffer;
 	OBJ_DATA *obj;
 	OBJ_DATA *in_obj;
@@ -1822,7 +1841,7 @@
 
 	buffer = new_buf();
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Find what?");
 		return;
@@ -1842,19 +1861,16 @@
 
 		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);
+			bprintlnf(buffer, "%3d) %s is carried by %s [Room %ld]",
+					  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);
+			bprintlnf(buffer, "%3d) %s is in %s [Room %ld]", 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);
+			bprintlnf(buffer, "%3d) %s is somewhere", number, obj->short_descr);
 
 		if (number >= max_found)
 			break;
@@ -1863,20 +1879,19 @@
 	if (!found)
 		chprintln(ch, "Nothing like that in heaven or earth.");
 	else
-		page_to_char(buf_string(buffer), ch);
+		sendpage(ch, buf_string(buffer));
 
 	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')
+	if (IS_NULLSTR(argument))
 	{
 		DESCRIPTOR_DATA *d;
 
@@ -1893,20 +1908,19 @@
 				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);
+					bprintlnf(buffer,
+							  "%3d) %s (in the body of %s) is in %s [%ld]",
+							  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);
+					bprintlnf(buffer, "%3d) %s is in %s [%ld]",
+							  count, victim->name,
+							  victim->in_room->name, victim->in_room->vnum);
 			}
 		}
 
-		page_to_char(buf_string(buffer), ch);
+		sendpage(ch, buf_string(buffer));
 		free_buf(buffer);
 		return;
 	}
@@ -1919,39 +1933,237 @@
 		{
 			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);
+			bprintlnf(buffer, "%3d) [%5ld] %-28s [%5ld] %s", count,
+					  IS_NPC(victim) ? victim->pIndexData->vnum : 0,
+					  IS_NPC(victim) ? victim->short_descr : victim->name,
+					  victim->in_room->vnum, victim->in_room->name);
 		}
 	}
 
 	if (!found)
 		act("You didn't find any $T.", ch, NULL, argument, TO_CHAR);
 	else
-		page_to_char(buf_string(buffer), ch);
+		sendpage(ch, buf_string(buffer));
 
 	free_buf(buffer);
 
 	return;
 }
 
-void set_shutdown(bool down)
+long get_seconds(long value, const char *arg)
 {
-	extern bool merc_down;
+	if (is_number(arg))
+		return value * atol(arg);
+	else if (!str_prefix(arg, "seconds"))
+		return value * SECOND;
+	else if (!str_prefix(arg, "minutes"))
+		return value * MINUTE;
+	else if (!str_prefix(arg, "hours"))
+		return value * HOUR;
+	else if (!str_prefix(arg, "days"))
+		return value * DAY;
+	else
+		return value;
+}
 
-	while (auction_first != NULL)
-		reset_auc(auction_first, TRUE);
-	save_donation_pit();
-	save_gquest_data();
-	save_war_data();
-	do_asave(NULL, "changed");
-#if !defined(NO_WEB)
-	if (WebUP)
-		shutdown_web_server();
-#endif
-	merc_down = down;
+const char *crs_type_name(crs_t type)
+{
+	switch (type)
+	{
+	case CRS_COPYOVER:
+		return "Copyover";
+	case CRS_REBOOT:
+		return "Reboot";
+	case CRS_SHUTDOWN:
+		return "Shutdown";
+	default:
+		return "Unknown";
+	}
+}
+
+PROTOTYPE(void copyover, (void));
+PROTOTYPE(void reboot_mud, (void));
+PROTOTYPE(void shutdown_mud, (void));
+
+void crs_fun(crs_t type)
+{								// Weeeeeeee
+	switch (type)
+	{
+	case CRS_COPYOVER:
+		copyover();
+		break;
+	case CRS_REBOOT:
+		reboot_mud();
+		break;
+	case CRS_SHUTDOWN:
+		shutdown_mud();
+		break;
+	default:
+		bug("crs_fun: bad type");
+		break;
+	}
+}
+
+void crs_update(void)
+{
+	if (crs_info.status == CRS_NONE || crs_info.timer <= 0)
+		return;
+
+	--crs_info.timer;
+
+	if (crs_info.timer % PULSE_PER_SECOND != 0)
+		return;
+
+	switch (crs_info.timer / PULSE_PER_SECOND)
+	{
+	case 0:
+		crs_fun(crs_info.status);
+		break;
+	case 1:
+	case 2:
+	case 3:
+	case 30:
+	case MINUTE:
+	case MINUTE * 3:
+	case MINUTE * 5:
+	case MINUTE * 10:
+	case MINUTE * 15:
+	case MINUTE * 20:
+	case MINUTE * 30:
+		announce(NULL, INFO_ALL, crs_sprintf(TRUE, FALSE));
+		break;
+	}
+}
+
+const char *format_pulse(int time)
+{
+	static char buf[5][100];
+	static int i;
+	char temp[100];
+	double timer = time / PULSE_PER_SECOND;
+
+	++i;
+	i %= 5;
+
+	sprintf(temp, "%%.%sf %s%%s",
+			(timer < MINUTE
+			 || (int) timer % MINUTE == 0) ? "" : "2",
+			timer >= MINUTE ? "minute" : "second");
+	sprintf(buf[i], temp, timer >= MINUTE ? timer / MINUTE : timer,
+			(timer == MINUTE || timer == 1) ? "" : "s");
+	return buf[i];
+}
+
+const char *crs_sprintf(bool pTime, bool reason)
+{
+	char buf[MSL];
+	const char *prstr;
+
+	if (crs_info.status == CRS_NONE || (pTime && crs_info.timer < 0))
+		return "";
+
+	if (reason)
+		prstr = crs_info.reason;
+	else
+		prstr = "";
+
+	if (pTime)
+	{
+		sprintf(buf, "%s by %s in %s.%s",
+				crs_type_name(crs_info.status),
+				!IS_NULLSTR(crs_info.who) ? crs_info.who : "System",
+				format_pulse(crs_info.timer), prstr);
+	}
+	else
+	{
+		sprintf(buf, "%s by %s.%s%s",
+				crs_type_name(crs_info.status),
+				!IS_NULLSTR(crs_info.who) ? crs_info.who : "System",
+				prstr,
+				crs_info.status == CRS_COPYOVER ? " Please wait....." : "");
+	}
+	return smash_colour(buf);
+}
+
+void do_crs(CHAR_DATA * ch, const char *argument, crs_t type)
+{
+	char arg[MIL], arg2[MIL];
+	int value = -1;
+	const char *cmd_name = crs_type_name(type);
+
+	argument = one_argument(argument, arg);
+
+	if (IS_NULLSTR(arg))
+	{
+		chprintlnf(ch, "Usage: %s now [reason]", cmd_name);
+		chprintlnf(ch, "Usage: %s <#value> <#mod> [reason]", cmd_name);
+		chprintlnf(ch, "Usage: %s cancel [why]", cmd_name);
+		chprintlnf(ch, "Usage: %s status", cmd_name);
+		return;
+	}
+
+	if (!str_cmp(arg, "cancel"))
+	{
+		crs_info.timer = -1;
+		replace_string(crs_info.who, "");
+		replace_string(crs_info.reason, "");
+		crs_info.status = CRS_NONE;
+		announce(ch, INFO_ALL, "$n has cancelled the %s.", cmd_name);
+		announce(ch, INFO_ALL | INFO_PRIVATE,
+				 "You have cancelled the %s.", cmd_name);
+		return;
+	}
+
+	if (!str_cmp(arg, "status"))
+	{
+		if (crs_info.timer == -1 || crs_info.status != type)
+			chprintlnf(ch, "Automatic %s is inactive.", cmd_name);
+		else
+			chprintln(ch, crs_sprintf(TRUE, TRUE));
+		return;
+	}
+
+	if (!str_cmp(arg, "now"))
+	{
+		crs_info.status = type;
+		replace_string(crs_info.who,
+					   (ch->invis_level > 0 ? "an Immortal" : ch->name));
+		if (!IS_NULLSTR(argument))
+			replace_string(crs_info.reason, FORMATF(" (%s)", argument));
+		crs_fun(crs_info.status);
+		return;
+	}
+
+	if (!str_cmp(arg, "random"))
+		value = number_range(60, 360);
+	else if (is_number(arg))
+		value = atoi(arg);
+	else
+	{
+		chprintln(ch, "Thats not a valid value.");
+		return;
+	}
+
+	argument = one_argument(argument, arg2);
+
+	if (IS_NULLSTR(arg2) || !is_name(arg2, "seconds minutes hours days"))
+	{
+		chprintlnf(ch, "Syntax: %s %d seconds/minutes/hours/days.", cmd_name,
+				   value);
+		return;
+	}
+
+	value = get_seconds(value, arg2);
+	value *= PULSE_PER_SECOND;
+	crs_info.timer = value;
+
+	if (!IS_NULLSTR(argument))
+		replace_string(crs_info.reason, FORMATF(" (%s)", argument));
+
+	replace_string(crs_info.who,
+				   (ch->invis_level > 0 ? "an Immortal" : ch->name));
+	crs_info.status = type;
+	announce(NULL, INFO_ALL, crs_sprintf(TRUE, FALSE));
 }
 
 CH_CMD(do_reboo)
@@ -1962,25 +2174,31 @@
 
 CH_CMD(do_reboot)
 {
-	char buf[MAX_STRING_LENGTH];
+	do_crs(ch, argument, CRS_REBOOT);
+	return;
+}
+
+void reboot_mud(void)
+{
 	DESCRIPTOR_DATA *d, *d_next;
 	CHAR_DATA *vch;
 
-	if (ch && ch->invis_level < LEVEL_HERO)
-	{
-		sprintf(buf, "Reboot by %s.", ch->name);
-		do_function(ch, &do_echo, buf);
-	}
-	set_shutdown(TRUE);
+	logf(crs_sprintf(FALSE, TRUE));
+
 	for (d = descriptor_first; d != NULL; d = d_next)
 	{
 		d_next = d->next;
-		vch = d->original ? d->original : d->character;
+		d_write(d, "\n\r", 2);
+		d_write(d, crs_sprintf(FALSE, TRUE), 0);
+		d_write(d, "\n\r", 2);
+		vch = CH(d);
 		if (vch != NULL)
+		{
 			save_char_obj(vch);
+		}
 		close_socket(d);
 	}
-
+	run_level = RUNLEVEL_SHUTDOWN;
 	return;
 }
 
@@ -1992,27 +2210,30 @@
 
 CH_CMD(do_shutdown)
 {
-	char buf[MAX_STRING_LENGTH];
+	do_crs(ch, argument, CRS_SHUTDOWN);
+	return;
+}
+
+void shutdown_mud()
+{
 	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 && ch->invis_level < LEVEL_HERO)
-	{
-		do_function(ch, &do_echo, buf);
-	}
-	set_shutdown(TRUE);
+	append_file(NULL, SHUTDOWN_FILE, crs_sprintf(FALSE, TRUE));
 	for (d = descriptor_first; d != NULL; d = d_next)
 	{
 		d_next = d->next;
-		vch = d->original ? d->original : d->character;
+		d_write(d, "\n\r", 2);
+		d_write(d, crs_sprintf(FALSE, TRUE), 0);
+		d_write(d, "\n\r", 2);
+		vch = CH(d);
 		if (vch != NULL)
+		{
 			save_char_obj(vch);
+		}
 		close_socket(d);
 	}
+	run_level = RUNLEVEL_SHUTDOWN;
 	return;
 }
 
@@ -2020,7 +2241,7 @@
 {
 	CHAR_DATA *victim;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Protect whom from snooping?");
 		return;
@@ -2056,7 +2277,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Snoop whom?");
 		return;
@@ -2135,7 +2356,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Switch into whom?");
 		return;
@@ -2191,9 +2412,10 @@
 	ch->desc = NULL;
 	/* change communications to match */
 	if (ch->prompt != NULL)
-		victim->prompt = str_dup(ch->prompt);
+		replace_string(victim->prompt, ch->prompt);
 	victim->comm = ch->comm;
 	victim->lines = ch->lines;
+	victim->columns = ch->columns;
 	chprintln(victim, "Ok.");
 	return;
 }
@@ -2269,7 +2491,7 @@
 
 	rest = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Clone what?");
 		return;
@@ -2383,7 +2605,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Syntax:");
 		chprintln(ch, "  load mob <vnum>");
@@ -2415,7 +2637,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0' || !is_number(arg))
+	if (IS_NULLSTR(arg) || !is_number(arg))
 	{
 		chprintln(ch, "Syntax: load mob <vnum>.");
 		return;
@@ -2446,7 +2668,7 @@
 	argument = one_argument(argument, arg1);
 	one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || !is_number(arg1))
+	if (IS_NULLSTR(arg1) || !is_number(arg1))
 	{
 		chprintln(ch, "Syntax: load obj <vnum> <level>.");
 		return;
@@ -2454,7 +2676,7 @@
 
 	level = get_trust(ch);		/* default */
 
-	if (arg2[0] != '\0')		/* load with a level */
+	if (!IS_NULLSTR(arg2))		/* load with a level */
 	{
 		if (!is_number(arg2))
 		{
@@ -2495,7 +2717,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		/* 'purge' */
 		CHAR_DATA *vnext;
@@ -2571,7 +2793,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0' || !is_number(arg2))
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || !is_number(arg2))
 	{
 		chprintln(ch, "Syntax: advance <char> <level>.");
 		return;
@@ -2656,7 +2878,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0' || !is_number(arg2))
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || !is_number(arg2))
 	{
 		chprintln(ch, "Syntax: trust <char> <level>.");
 		return;
@@ -2692,7 +2914,7 @@
 	DESCRIPTOR_DATA *d;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0' || !str_cmp(arg, "room"))
+	if (IS_NULLSTR(arg) || !str_cmp(arg, "room"))
 	{
 		/* cure room */
 
@@ -2778,7 +3000,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Freeze whom?");
 		return;
@@ -2831,7 +3053,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Log whom?");
 		return;
@@ -2839,14 +3061,14 @@
 
 	if (!str_cmp(arg, "all"))
 	{
-		if (fLogAll)
+		if (IS_SET(mud_info.mud_flags, MUD_LOGALL))
 		{
-			fLogAll = FALSE;
+			REMOVE_BIT(mud_info.mud_flags, MUD_LOGALL);
 			chprintln(ch, "Log ALL off.");
 		}
 		else
 		{
-			fLogAll = TRUE;
+			SET_BIT(mud_info.mud_flags, MUD_LOGALL);
 			chprintln(ch, "Log ALL on.");
 		}
 		return;
@@ -2888,7 +3110,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Noemote whom?");
 		return;
@@ -2933,7 +3155,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Noshout whom?");
 		return;
@@ -2984,7 +3206,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Notell whom?");
 		return;
@@ -3040,18 +3262,17 @@
 
 CH_CMD(do_wizlock)
 {
-	extern bool wizlock;
-	wizlock = !wizlock;
-
-	if (wizlock)
+	if (!IS_SET(mud_info.mud_flags, MUD_WIZLOCK))
 	{
 		wiznet("$N has wizlocked the game.", ch, NULL, 0, 0, 0);
 		chprintln(ch, "Game wizlocked.");
+		SET_BIT(mud_info.mud_flags, MUD_WIZLOCK);
 	}
 	else
 	{
 		wiznet("$N removes wizlock.", ch, NULL, 0, 0, 0);
 		chprintln(ch, "Game un-wizlocked.");
+		REMOVE_BIT(mud_info.mud_flags, MUD_WIZLOCK);
 	}
 
 	return;
@@ -3061,18 +3282,17 @@
 
 CH_CMD(do_newlock)
 {
-	extern bool newlock;
-	newlock = !newlock;
-
-	if (newlock)
+	if (!IS_SET(mud_info.mud_flags, MUD_NEWLOCK))
 	{
 		wiznet("$N locks out new characters.", ch, NULL, 0, 0, 0);
 		chprintln(ch, "New characters have been locked out.");
+		SET_BIT(mud_info.mud_flags, MUD_NEWLOCK);
 	}
 	else
 	{
 		wiznet("$N allows new characters back in.", ch, NULL, 0, 0, 0);
 		chprintln(ch, "Newlock removed.");
+		REMOVE_BIT(mud_info.mud_flags, MUD_NEWLOCK);
 	}
 
 	return;
@@ -3084,7 +3304,7 @@
 	int sn;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Lookup which skill or spell?");
 		return;
@@ -3114,51 +3334,6 @@
 	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];
@@ -3173,7 +3348,7 @@
 	argument = one_argument(argument, arg2);
 	argument = one_argument(argument, arg3);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || IS_NULLSTR(arg3))
 	{
 		chprintln(ch, "Syntax:");
 		chprintln(ch, "  set skill <name> <spell or skill> <value>");
@@ -3234,927 +3409,93 @@
 	return;
 }
 
-CH_CMD(do_mset)
+CH_CMD(do_sockets)
 {
-	char arg1[MAX_INPUT_LENGTH];
-	char arg2[MAX_INPUT_LENGTH];
-	char arg3[MAX_INPUT_LENGTH];
-	CHAR_DATA *victim;
-	long value;
+	char buf[2 * MAX_STRING_LENGTH];
+	char buf2[MAX_STRING_LENGTH];
+	char arg[MAX_INPUT_LENGTH];
+	DESCRIPTOR_DATA *d;
+	int count;
 
-	smash_tilde(argument);
-	argument = one_argument(argument, arg1);
-	argument = one_argument(argument, arg2);
-	strcpy(arg3, argument);
+	count = 0;
+	buf[0] = '\0';
 
-	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
+	one_argument(argument, arg);
+	for (d = descriptor_first; d != NULL; d = d->next)
 	{
-		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 (d->character != NULL && can_see(ch, d->character) &&
+			(IS_NULLSTR(arg) || 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 ((victim = get_char_world(ch, arg1)) == NULL)
+	if (count == 0)
 	{
-		chprintln(ch, "They aren't here.");
+		chprintln(ch, "No one by that name is connected.");
 		return;
 	}
 
-	/* clear zones for mobs */
-	victim->zone = NULL;
+	sprintf(buf2, "%d user%s\n\r", count, count == 1 ? "" : "s");
+	strcat(buf, buf2);
+	sendpage(ch, buf);
+	return;
+}
 
-	/*
-	 * Snarf the value (which need not be numeric).
-	 */
-	value = is_number(arg3) ? atol(arg3) : -1;
+/*
+ * 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];
 
-	/*
-	 * Set something.
-	 */
-	if (!str_cmp(arg2, "str"))
+	argument = one_argument(argument, arg);
+
+	if (IS_NULLSTR(arg) || IS_NULLSTR(argument))
 	{
-		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;
-		}
+		chprintln(ch, "Force whom to do what?");
+		return;
+	}
+
+	one_argument(argument, arg2);
 
-		victim->perm_stat[STAT_STR] = value;
+	if (!str_cmp(arg2, "delete") || !str_prefix(arg2, "mob"))
+	{
+		chprintln(ch, "That will NOT be done.");
 		return;
 	}
 
-	if (!str_cmp(arg2, "security"))	/* OLC */
+	sprintf(buf, "$n forces you to '%s'.", argument);
+
+	if (!str_cmp(arg, "all"))
 	{
-		if (IS_NPC(ch))
-		{
-			chprintln(ch, "Si, claro.");
-			return;
-		}
+		CHAR_DATA *vch;
+		CHAR_DATA *vch_next;
 
-		if (IS_NPC(victim))
+		if (get_trust(ch) < MAX_LEVEL - 3)
 		{
-			chprintln(ch, "Not on NPC's.");
+			chprintln(ch, "Not at your level!");
 			return;
 		}
 
-		if (value > ch->pcdata->security || value < 0)
+		for (vch = char_first; vch != NULL; vch = vch_next)
 		{
-			if (ch->pcdata->security != 0)
-			{
-				chprintlnf(ch, "Valid security is 0-%d.", ch->pcdata->security);
-			}
-			else
+			vch_next = vch->next;
+
+			if (!IS_NPC(vch) && get_trust(vch) < get_trust(ch))
 			{
-				chprintln(ch, "Valid security is 0 only.");
+				act(buf, ch, NULL, vch, TO_VICT);
+				interpret(vch, argument);
 			}
-			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))
-			{
-				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"))
+	else if (!str_cmp(arg, "players"))
 	{
 		CHAR_DATA *vch;
 		CHAR_DATA *vch_next;
@@ -4255,7 +3596,7 @@
 	/* RT code for taking a level argument */
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 		/* take the default path */
 
 		if (ch->invis_level)
@@ -4299,7 +3640,7 @@
 	/* RT code for taking a level argument */
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 		/* take the default path */
 
 		if (ch->incog_level)
@@ -4366,73 +3707,72 @@
 {
 	char buf[MAX_INPUT_LENGTH];
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
-		if (ch->prefix[0] == '\0')
+		if (IS_NULLSTR(ch->prefix))
 		{
 			chprintln(ch, "You have no prefix to clear.");
 			return;
 		}
 
 		chprintln(ch, "Prefix removed.");
-		free_string(ch->prefix);
-		ch->prefix = str_dup("");
+		replace_string(ch->prefix, "");
 		return;
 	}
 
-	if (ch->prefix[0] != '\0')
+	if (!IS_NULLSTR(ch->prefix))
 	{
 		sprintf(buf, "Prefix changed to %s.\r\n", argument);
-		free_string(ch->prefix);
+		replace_string(ch->prefix, argument);
 	}
 	else
 	{
 		sprintf(buf, "Prefix set to %s.\r\n", argument);
+		replace_string(ch->prefix, argument);
 	}
-
-	ch->prefix = str_dup(argument);
 }
 
-/* This file holds the copyover data */
-#define COPYOVER_FILE   DATA_DIR "copyover.dat"
-
-/* 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 :)
  */
+ /* Updated by Markanth 08/06/2003. */
+
+CH_CMD(do_copyove)
+{
+	chprintln(ch, "If you want to COPYOVER, spell it out.");
+	return;
+}
+
 CH_CMD(do_copyover)
 {
-#if defined(WIN32) || defined(__CYGWIN__)
-	chprintln(ch, "Copyover is disabled under windows.");
+#if defined(NO_COPYOVER)
+	chprintln(ch, "Copyover is disabled.");
 #else
-	FILE *fp;
+	do_crs(ch, argument, CRS_COPYOVER);
+#endif
+	return;
+}
+
+void copyover(void)
+{
+#if !defined(NO_COPYOVER)
+	WRITE_DATA *fp;
 	DESCRIPTOR_DATA *d, *d_next;
 	char buf[100], buf2[100];
-	extern int port, control;	/* db.c */
+	extern bool verbose_log;
 
-	fp = file_open(COPYOVER_FILE, "w");
+	fp = open_write(COPYOVER_FILE);
 
 	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");
+		log_error("do_copyover:file open");
 		return;
 	}
 
-	set_vtimer(-1);
-
-	/* Consider changing all saved areas here, if you use OLC */
-
-	set_shutdown(FALSE);
-
-	sprintf(buf, "\n\r *** COPYOVER by %s - please remain seated!\n\r",
-			ch ? ch->name : "System");
+	crs_info.status = CRS_COPYOVER;
 
 	/* For each playing descriptor, save its state */
 	for (d = descriptor_first; d; d = d_next)
@@ -4441,83 +3781,81 @@
 		d_next = d->next;		/* We delete from the list , so need to save this */
 
 #if !defined(NO_MCCP)
-		compressEnd(d);
+		compressEnd(d, d->mccp_version);
 #endif
 
-		if (!d->character || d->connected > CON_PLAYING)	/* drop those logging on */
+		if (!och || 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);
+			d_write(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);
+			fprintf(fp->stream, "%d %s\n", d->descriptor, och->name);
 
-#if 0							/* This is not necessary for ROM */
-			if (och->level == 1)
+			if (och->fighting != NULL)
 			{
-				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 */
+				stop_fighting(och->fighting, TRUE);
+				stop_fighting(och, TRUE);
 			}
-#endif
+			extract_arena(och);
+
+			update_pos(och);
 			save_char_obj(och);
 
-			write_to_descriptor(d, buf, 0);
+			d_write(d, "\n\r", 2);
+			d_write(d, crs_sprintf(FALSE, TRUE), 0);
+			d_write(d, "\n\r", 2);
 		}
 	}
 
-	fprintf(fp, "-1\n");
-	file_close(fp);
+	fprintf(fp->stream, "-1\n");
+	close_write(fp);
 
 	/* Close reserve and other always-open files and release other resources */
 
-	fclose(fpReserve);
+	cleanup_mud();				// don't move this
 
 	/* exec - descriptors are inherited */
 
 	sprintf(buf, "%d", port);
 	sprintf(buf2, "%d", control);
-	execl(EXE_FILE, "rom", buf, "copyover", buf2, (char *) NULL);
 
+	if (verbose_log)
+		execl(EXE_FILE, EXE_FILE, buf, "-v", "-c", buf2, (char *) NULL);
+	else
+		execl(EXE_FILE, EXE_FILE, buf, "-c", buf2, (char *) NULL);
 	/* Failed - sucessful exec will not return */
 
-	perror("do_copyover: execl");
-	chprintln(ch, "Copyover FAILED!");
+	log_error("do_copyover: execl");
+	announce(NULL, INFO_ALL, "Copyover FAILED!");
 
 	/* Here you might want to reopen fpReserve */
-	fpReserve = fopen(NULL_FILE, "r");
+	if (fpReserve == NULL)
+		fpReserve = fopen(NULL_FILE, "r");
 #endif
 }
 
-#if !defined(WIN32) && !defined(__CYGWIN__)
+#if !defined(NO_COPYOVER)
 /* Recover from a copyover - load players */
 void copyover_recover()
 {
 	DESCRIPTOR_DATA *d;
-	FILE *fp;
-	char name[100];
-	char host[MSL];
+	READ_DATA *fp;
+	char *name;
 	int desc;
-	long dflags;
 	bool fOld;
 
 	logf("Copyover recovery initiated");
+	crs_info.status = CRS_COPYOVER_RECOVER;
 
-	set_vtimer(-1);
-
-	fp = file_open(COPYOVER_FILE, "r");
+	fp = open_read(COPYOVER_FILE);
 
 	if (!fp)					/* there are some descriptors open which will hang forever then ? */
 	{
-		perror("copyover_recover:file_open");
+		log_error("copyover_recover:file open");
 		logf("Copyover file not found. Exitting.\n\r");
 		exit(1);
 	}
@@ -4526,23 +3864,21 @@
 
 	for (;;)
 	{
-		fscanf(fp, "%d %s %s %ld\n", &desc, name, host, &dflags);
+		desc = read_number(fp);
+
 		if (desc == -1)
 			break;
 
+		name = read_word(fp);
+
 		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))
+		if (!d_write(d, "\n\rRestoring from copyover...\n\r", 0))
 		{
-			close(desc);		/* nope */
+			close_socket(d);	/* nope */
 			continue;
 		}
 
@@ -4552,14 +3888,14 @@
 
 		if (!fOld)				/* Player file not found?! */
 		{
-			write_to_descriptor(d,
-								"\n\rSomehow, your character was lost in the copyover. Sorry.\n\r",
-								0);
+			d_write(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);
+			d_write(d, "\n\rCopyover recovery complete.\n\r", 0);
 
 			/* Just In Case */
 			if (!d->character->in_room)
@@ -4571,6 +3907,14 @@
 			LINK(d->character, player_first, player_last, next_player,
 				 prev_player);
 
+#if !defined(NO_MCCP)
+			if (d->mccp_version > 0)
+				compressStart(d, d->mccp_version);
+#endif
+
+			update_explored(d->character);
+			update_all_qobjs(d->character);
+
 			char_to_room(d->character, d->character->in_room);
 			do_look(d->character, "auto");
 			checkcorpse(d->character);
@@ -4586,8 +3930,8 @@
 		}
 
 	}
-	file_close(fp);
-
+	close_read(fp);
+	crs_info.status = CRS_NONE;
 }
 #endif
 
@@ -4704,7 +4048,7 @@
 	bool isChar = FALSE;
 	char name[MAX_INPUT_LENGTH];
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Load who?");
 		return;
diff -ur -x config -x o -x rom src/alias.c new/alias.c
--- src/alias.c	Tue May 27 02:46:35 2003
+++ new/alias.c	Sun Aug 31 19:23:20 2003
@@ -22,14 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "proto.h"
@@ -46,7 +42,7 @@
 	ch = d->original ? d->original : d->character;
 
 	/* check for prefix */
-	if (ch->prefix[0] != '\0' && str_prefix("prefix", argument))
+	if (!IS_NULLSTR(ch->prefix) && str_prefix("prefix", argument))
 	{
 		if (strlen(ch->prefix) + strlen(argument) > MAX_INPUT_LENGTH - 2)
 			chprintln(ch, "Line to long, prefix not processed.");
@@ -122,7 +118,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 
 		if (rch->pcdata->alias[0] == NULL)
@@ -150,7 +146,7 @@
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		for (pos = 0; pos < MAX_ALIAS; pos++)
 		{
@@ -184,8 +180,7 @@
 
 		if (!str_cmp(arg, rch->pcdata->alias[pos]))	/* redefine an alias */
 		{
-			free_string(rch->pcdata->alias_sub[pos]);
-			rch->pcdata->alias_sub[pos] = str_dup(argument);
+			replace_string(rch->pcdata->alias_sub[pos], argument);
 			chprintlnf(ch, "%s is now realiased to '%s'.", arg, argument);
 			return;
 		}
@@ -220,7 +215,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Unalias what?");
 		return;
diff -ur -x config -x o -x rom src/ansi.h new/ansi.h
--- src/ansi.h	Tue May 27 02:46:36 2003
+++ new/ansi.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 #if !defined(ANSI_H)
@@ -64,6 +64,11 @@
 #define CL_REVERSE		 7
 #define CL_HIDDEN		 8
 #define CL_RANDOM        -1
+
+#define CT_ATTR			0
+#define CT_FORE			1
+#define CT_BACK			2
+#define CT_MAX			3
 
 #define CL_DEFAULT		"\033[0m"
 
diff -ur -x config -x o -x rom src/arena.c new/arena.c
--- src/arena.c	Tue May 27 02:46:35 2003
+++ new/arena.c	Sun Aug 31 19:23:20 2003
@@ -22,21 +22,15 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
 #include "merc.h"
 #include "tables.h"
 #include "recycle.h"
 #include "interp.h"
 
-void death_cry args((CHAR_DATA * ch));
+PROTOTYPE(void death_cry, (CHAR_DATA *));
 
 CH_CMD(do_arena_challenge)
 {
@@ -52,7 +46,7 @@
 		return;
 	}
 
-	if (arena == FIGHT_START)
+	if (mud_info.arena == FIGHT_START)
 	{
 		chprintln
 			(ch,
@@ -60,7 +54,7 @@
 		return;
 	}
 
-	if (arena == FIGHT_BUSY)
+	if (mud_info.arena == FIGHT_BUSY)
 	{
 		chprintln
 			(ch,
@@ -68,19 +62,18 @@
 		return;
 	}
 
-	if (arena == FIGHT_LOCK)
+	if (mud_info.arena == FIGHT_LOCK)
 	{
 		chprintln(ch, "Sorry, the arena is currently locked from use.");
 		return;
 	}
 
-	if (IS_SET(ch->act, PLR_CHALLENGED))
+	if (ch->pcdata->challenger)
 	{
 		chprintlnf
 			(ch,
 			 "You have already been challenged, either ACCEPT or DECLINE %s first.",
-			 ch->pcdata->challenger ? ch->pcdata->challenger->name : ch->
-			 pcdata->challenged ? ch->pcdata->challenged->name : "!BUG!");
+			 ch->pcdata->challenger->name);
 		return;
 	}
 
@@ -90,7 +83,7 @@
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "You must specify whom you wish to challenge.");
 		return;
@@ -114,7 +107,7 @@
 		return;
 	}
 
-	if (IS_SET(victim->act, PLR_CHALLENGER))
+	if (victim->pcdata->challenger)
 	{
 		chprintln(ch, "They have already challenged someone else.");
 		return;
@@ -139,10 +132,8 @@
 	}
 
 	ch->pcdata->challenged = victim;
-	SET_BIT(ch->act, PLR_CHALLENGER);
 	victim->pcdata->challenger = ch;
-	SET_BIT(victim->act, PLR_CHALLENGED);
-	arena = FIGHT_START;
+	mud_info.arena = FIGHT_START;
 	chprintln
 		(ch,
 		 "Challenge has been sent.  Type 'arena challenge drop' to cancel the challenge.");
@@ -174,13 +165,13 @@
 	if (IS_NPC(ch))
 		return;
 
-	if (!IS_SET(ch->act, PLR_CHALLENGED))
+	if (!ch->pcdata->challenger)
 	{
 		chprintln(ch, "You have not been challenged.");
 		return;
 	}
 
-	if (arena == FIGHT_BUSY)
+	if (mud_info.arena == FIGHT_BUSY)
 	{
 		chprintln
 			(ch,
@@ -188,13 +179,13 @@
 		return;
 	}
 
-	if (arena == FIGHT_LOCK)
+	if (mud_info.arena == FIGHT_LOCK)
 	{
 		chprintln(ch, "Sorry, the arena is currently locked from use.");
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "You must specify whose challenge you wish to accept.");
 		return;
@@ -212,8 +203,7 @@
 		return;
 	}
 
-	if (!IS_SET(victim->act, PLR_CHALLENGER)
-		|| victim != ch->pcdata->challenger)
+	if (!victim->pcdata->challenged || victim != ch->pcdata->challenger)
 	{
 		chprintln(ch, "That player hasn't challenged you!");
 		return;
@@ -242,7 +232,7 @@
 	char_from_room(victim);
 	char_to_room(victim, random2);
 	do_function(victim, &do_look, "auto");
-	arena = FIGHT_BUSY;
+	mud_info.arena = FIGHT_BUSY;
 	return;
 }
 
@@ -253,13 +243,13 @@
 	if (IS_NPC(ch))
 		return;
 
-	if (!IS_SET(ch->act, PLR_CHALLENGED))
+	if (!ch->pcdata->challenger)
 	{
 		chprintln(ch, "You have not been challenged.");
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "You must specify whose challenge you wish to decline.");
 		return;
@@ -271,8 +261,7 @@
 		return;
 	}
 
-	if (!IS_SET(victim->act, PLR_CHALLENGER)
-		|| victim != ch->pcdata->challenger)
+	if (!victim->pcdata->challenged || victim != ch->pcdata->challenger)
 	{
 		chprintln(ch, "That player hasn't challenged you.");
 		return;
@@ -281,11 +270,11 @@
 	if (victim == ch)
 		return;
 
+	ch->pcdata->challenged = NULL;
 	victim->pcdata->challenged = NULL;
-	REMOVE_BIT(victim->act, PLR_CHALLENGER);
 	ch->pcdata->challenger = NULL;
-	REMOVE_BIT(ch->act, PLR_CHALLENGED);
-	arena = FIGHT_OPEN;
+	victim->pcdata->challenger = NULL;
+	mud_info.arena = FIGHT_OPEN;
 	chprintln(ch, "Challenge declined!");
 	act("$n has declined your challenge.", ch, NULL, victim, TO_VICT);
 	announce(ch, INFO_ARENA, "$n has declined %s's challenge.", victim->name);
@@ -304,7 +293,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (argument[0] == '\0' || !is_number(arg))
+	if (IS_NULLSTR(argument) || !is_number(arg))
 	{
 		chprintln(ch, "Syntax: BET [amount] [player]");
 		return;
@@ -316,7 +305,7 @@
 		return;
 	}
 
-	if (IS_SET(ch->act, PLR_CHALLENGER) || IS_SET(ch->act, PLR_CHALLENGED))
+	if (ch->pcdata->challenger || ch->pcdata->challenged)
 	{
 		chprintln(ch, "You can't bet on this battle.");
 		return;
@@ -427,38 +416,25 @@
 	update_pos(ch);
 	do_function(ch, &do_look, "auto");
 
-	if (IS_SET(ch->act, PLR_CHALLENGER))
-		REMOVE_BIT(ch->act, PLR_CHALLENGER);
-	if (IS_SET(victim->act, PLR_CHALLENGER))
-		REMOVE_BIT(victim->act, PLR_CHALLENGER);
-	if (IS_SET(victim->act, PLR_CHALLENGED))
-		REMOVE_BIT(victim->act, PLR_CHALLENGED);
-	if (IS_SET(ch->act, PLR_CHALLENGED))
-		REMOVE_BIT(ch->act, PLR_CHALLENGED);
-
 	ch->pcdata->challenger = NULL;
 	ch->pcdata->challenged = NULL;
 	victim->pcdata->challenger = NULL;
 	victim->pcdata->challenged = NULL;
 
-	arena = FIGHT_OPEN;
+	mud_info.arena = FIGHT_OPEN;
 
 	return;
 }
 
 void extract_arena(CHAR_DATA * ch)
 {
-	if (IS_SET(ch->act, PLR_CHALLENGED) && arena == FIGHT_START
-		&& ch->pcdata->challenger != NULL)
+	if (mud_info.arena == FIGHT_START && ch->pcdata->challenger != NULL)
 		do_function(ch, &do_arena_decline, ch->pcdata->challenger->name);
-	if (IS_SET(ch->act, PLR_CHALLENGER) && arena == FIGHT_START
-		&& ch->pcdata->challenged != NULL)
+	if (mud_info.arena == FIGHT_START && ch->pcdata->challenged != NULL)
 	{
-		REMOVE_BIT(ch->act, PLR_CHALLENGER);
-		REMOVE_BIT(ch->pcdata->challenged->act, PLR_CHALLENGED);
 		ch->pcdata->challenged->pcdata->challenger = NULL;
 		ch->pcdata->challenged = NULL;
-		arena = FIGHT_OPEN;
+		mud_info.arena = FIGHT_OPEN;
 	}
 }
 
@@ -470,7 +446,7 @@
 	if (IS_NPC(ch))
 		return FALSE;
 
-	if (!IS_SET(ch->act, PLR_CHALLENGED) && !IS_SET(ch->act, PLR_CHALLENGER))
+	if (!ch->pcdata->challenged && !ch->pcdata->challenger)
 		return FALSE;
 
 	if (!ch->in_room)
@@ -492,7 +468,7 @@
 	if (IS_IMMORTAL(ch))
 	{
 		chprintln(ch, "Imm Only: arena <clear|lock|busy>");
-		switch (arena)
+		switch (mud_info.arena)
 		{
 		case FIGHT_OPEN:
 			chprintln(ch, "Arena is [CLEAR]");
@@ -522,17 +498,15 @@
 		do_arena_help(ch, "");
 		return;
 	}
-	arena = FIGHT_OPEN;
+	mud_info.arena = FIGHT_OPEN;
 	chprintln(ch, "Arena now set [CLEARED]");
 	announce(NULL, INFO_ARENA, "The arena has been opened.");
 	for (d = descriptor_first; d != NULL; d = d->next)
 	{
 		if (d->connected == CON_PLAYING && d->character)
 		{
-			if (IS_SET(d->character->act, PLR_CHALLENGER))
-				REMOVE_BIT(d->character->act, PLR_CHALLENGER);
-			if (IS_SET(d->character->act, PLR_CHALLENGED))
-				REMOVE_BIT(d->character->act, PLR_CHALLENGED);
+			d->character->pcdata->challenger = NULL;
+			d->character->pcdata->challenged = NULL;
 			if (IS_SET(d->character->in_room->room_flags, ROOM_ARENA))
 			{
 				char_from_room(ch);
@@ -552,7 +526,7 @@
 		do_arena_help(ch, "");
 		return;
 	}
-	arena = FIGHT_BUSY;
+	mud_info.arena = FIGHT_BUSY;
 	chprintln(ch, "Arena now set [BUSY]");
 	announce(NULL, INFO_ARENA, "The arena is now busy.");
 	return;
@@ -566,7 +540,7 @@
 		do_arena_help(ch, "");
 		return;
 	}
-	arena = FIGHT_LOCK;
+	mud_info.arena = FIGHT_LOCK;
 	chprintln(ch, "Arena now set [LOCKED]");
 	announce(NULL, INFO_ARENA, "The arena has been locked.");
 	return;
diff -ur -x config -x o -x rom src/auction.c new/auction.c
--- src/auction.c	Tue May 27 02:46:35 2003
+++ new/auction.c	Sun Aug 31 19:23:20 2003
@@ -22,18 +22,9 @@
 *       By using this code, you have agreed to follow the terms of the    *
 *       ROM license, in the file Rom24/doc/rom.license                    *
 ***************************************************************************
-*     _/_/_/   _/      _/    _/           Devil's Lament MUD              *
-*    _/   _/  _/      _/ _/ _/      (c) 1999-2002 by Ryan Jennings        *
-*   _/   _/  _/      _/    _/          Telnet : <dlmud.com:3778>          *
-*  _/_/_/   _/_/_/  _/    _/           E-Mail : <dlmud@dlmud.com>         *
-*                                   Website: <http://www.dlmud.com/>      *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
+*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "olc.h"
 #include "magic.h"
@@ -221,12 +212,12 @@
 		if (!auc->item)
 		{
 			reset_auc(auc, TRUE);
-			bug("Auction with no item, reseting.", 0);
+			bugf("Auction with no item, reseting.");
 			continue;
 		}
-		else
+		else if (auc->status % PULSE_PER_SECOND == 0)
 		{
-			switch (auc->status)
+			switch (auc->status / PULSE_PER_SECOND)
 			{
 			case 0:
 				if (auc->high_bidder == NULL)
@@ -237,9 +228,9 @@
 					reset_auc(auc, TRUE);
 				}
 				else if ((unsigned long) (!IS_OBJ_STAT(auc->item, ITEM_QUEST)
-										  ? auc->high_bidder->
-										  gold : auc->high_bidder->pcdata->
-										  questpoints) < auc->bid)
+										  ? auc->high_bidder->gold : auc->
+										  high_bidder->pcdata->questpoints) <
+						 auc->bid)
 				{
 					announce(auc->high_bidder, INFO_AUCTION,
 							 "$n can't cover their stake in the auction, sale stopped.");
@@ -258,7 +249,7 @@
 					reset_auc(auc, FALSE);
 				}
 				break;
-			case PULSE_PER_SECOND * 30:
+			case 32:
 				announce(NULL, INFO_AUCTION,
 						 "Going once %s (Level %d, Num %d). Current bid is %ld%s.",
 						 auc->item->short_descr, auc->item->level,
@@ -266,7 +257,7 @@
 															ITEM_QUEST) ?
 						 "qp" : "g");
 				break;
-			case PULSE_PER_SECOND * 15:
+			case 15:
 				announce(NULL, INFO_AUCTION,
 						 "Going twice %s (Level %d, Num %d). Current bid is %ld%s.",
 						 auc->item->short_descr, auc->item->level,
@@ -287,7 +278,7 @@
 		if (IS_OBJ_STAT(auc->item, ITEM_AUCTIONED))
 			REMOVE_BIT(auc->item->extra_flags, ITEM_AUCTIONED);
 		else
-			bug("item not flagged auction item", 0);
+			bug("item not flagged auction item");
 
 		if (!forced && auc->high_bidder != NULL && auc->bid > 0)
 		{
@@ -496,7 +487,7 @@
 		chprintln(ch,
 				  "{GNum   Seller       Item Description                   Lvl   Last Bid    Time{x");
 		chprintln(ch,
-				  "{W---  ------------ ----------------------------------- --- ------------- ----{x");
+				  "{W---  ------------ ----------------------------------- --- ------------- ------------{x");
 		for (auc = auction_first; auc; auc = auc_next)
 		{
 			auc_next = auc->next;
@@ -507,18 +498,19 @@
 				continue;
 			}
 			if (!IS_OBJ_STAT(auc->item, ITEM_AUCTIONED))
-				bug("Auctioned item is not flaged Auctioned.", 0);
+				bug("Auctioned item is not flaged Auctioned.");
 
-			chprintlnf(ch, "{R%3d{x - %-12s %34s %3d {R%11ld%-2s{G %4d{x",
-					   auc->number, auc->owner->name,
+			chprintlnf(ch, "{R%3d{x - %-12s " MXPTAG("Bid %d") "%34s"
+					   MXPTAG("/Bid") " %3d {R%11ld%-2s{G %s{x",
+					   auc->number, auc->owner->name, auc->number,
 					   stringf(ch, 34, ALIGN_LEFT, NULL,
 							   auc->item->short_descr), auc->item->level,
 					   auc->bid, IS_OBJ_STAT(auc->item,
 											 ITEM_QUEST) ? "qp" : "g ",
-					   auc->status);
+					   format_pulse(auc->status));
 		}
 		chprintln(ch,
-				  "{W-----------------------------------------------------------------------------{x");
+				  "{W------------------------------------------------------------------------------------{x");
 		chprintln(ch,
 				  "Type: 'Bid <num>' to see stats and 'Bid <num> <amount>' to bid on an item.");
 		return;
@@ -619,7 +611,10 @@
 					 bid, IS_OBJ_STAT(auc->item,
 									  ITEM_QUEST) ? "quest points" : "gold",
 					 auc->item->short_descr);
-
+			chprintlnf(ch, "You offer %ld %s for %s.",
+					   bid, IS_OBJ_STAT(auc->item,
+										ITEM_QUEST) ? "quest points" : "gold",
+					   auc->item->short_descr);
 			auc->high_bidder = ch;
 			auc->bid = bid;
 			auc->status = AUCTION_LENGTH;
diff -ur -x config -x o -x rom src/automap.c new/automap.c
--- src/automap.c	Tue May 27 02:46:35 2003
+++ new/automap.c	Sun Aug 31 19:23:20 2003
@@ -22,19 +22,13 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 
 char map_chars[5] = "|-|-";
-char map_chars_closed[5] = "I>I<";
+char map_chars_closed[5] = "I=I=";
 char lcolor = 'x';
 int depth = 0;
 
@@ -47,7 +41,6 @@
 struct map_type
 {
 	char symbol;
-	vnum_t vnum;
 	int depth;
 	ROOM_INDEX_DATA *pRoom;
 };
@@ -85,27 +78,14 @@
 
 void clear_coord(int x, int y)
 {
-	map[x][y].symbol = '.';
-	map[x][y].vnum = 0;
+	map[x][y].symbol = ' ';
 	map[x][y].depth = 0;
 	map[x][y].pRoom = NULL;
 }
 
-void clear_room(int x, int y)
-{
-	int dir, exitx, exity;
-
-	for (dir = DIR_NORTH; dir <= DIR_WEST; dir++)
-	{
-		get_exit_dir(dir, &exitx, &exity, x, y);
-		if (!BOUNDARY(exitx, exity))
-			clear_coord(exitx, exity);
-	}
-}
-
 struct sector_color_type
 {
-	int bit;
+	sector_t bit;
 	const char *display_color;
 	char display_symbol;
 };
@@ -125,7 +105,7 @@
 	{SECT_MAX, "{w", 'o'}
 };
 
-const char *get_sector_color(int sector)
+const char *get_sector_color(sector_t sector)
 {
 	int looper;
 
@@ -136,7 +116,7 @@
 	return (sector_color_table[looper].display_color);
 }
 
-char get_sector_symbol(int sector)
+char get_sector_symbol(sector_t sector)
 {
 	int looper;
 
@@ -158,7 +138,6 @@
 		return;
 
 	map[x][y].symbol = get_sector_symbol(pRoom->sector_type);
-	map[x][y].vnum = pRoom->vnum;
 	map[x][y].depth = depth;
 	map[x][y].pRoom = pRoom;
 
@@ -170,6 +149,9 @@
 		if ((pExit = pRoom->exit[door]) == NULL)
 			continue;
 
+		if (IS_SET(pExit->exit_info, EX_CLOSED))
+			continue;
+
 		if (pExit->u1.to_room == NULL)
 			continue;
 
@@ -182,19 +164,10 @@
 		if (BOUNDARY(exitx, exity) || BOUNDARY(roomx, roomy))
 			continue;
 
-		if ((map[roomx][roomy].vnum != 0)
-			&& (map[roomx][roomy].vnum != pExit->u1.to_room->vnum)
-			/* only clear exits and rooms of higher depth */
-			&& map[roomx][roomy].depth > depth && depth < MAXDEPTH)
-		{
-			clear_room(roomx, roomy);
-		}
-
 		if (depth == MAXDEPTH)
 			continue;
 
 		map[exitx][exity].depth = depth;
-		map[exitx][exity].vnum = pExit->u1.to_room->vnum;
 		if (IS_SET(pExit->exit_info, EX_CLOSED))
 			map[exitx][exity].symbol = map_chars_closed[door];
 		else
@@ -202,8 +175,8 @@
 		map[exitx][exity].pRoom = pExit->u1.to_room;
 
 		if ((depth < MAXDEPTH)
-			&& ((map[roomx][roomy].vnum == pExit->u1.to_room->vnum)
-				|| (map[roomx][roomy].vnum == 0)))
+			&& ((map[roomx][roomy].pRoom == pExit->u1.to_room)
+				|| (map[roomx][roomy].pRoom == NULL)))
 		{
 			depth++;
 			map_exits(ch, pExit->u1.to_room, roomx, roomy);
@@ -222,7 +195,7 @@
 	m = 0;
 	buf[0] = '\0';
 
-	if (desc[0] == '\0')
+	if (IS_NULLSTR(desc))
 		return;
 
 	/* remove all \n & \r */
@@ -300,8 +273,7 @@
 	int rcnt = areacount(ch, ch->in_room->area);
 	double rooms = (double) (arearooms(ch->in_room->area));
 	double percent = UMIN((double) rcnt / (rooms / 100), 100);
-	int maxlen = (ch->desc
-				  && ch->desc->scr_width > 0) ? ch->desc->scr_width - 2 : 78;
+	int maxlen = get_scr_cols(ch);
 	int maplen = maxlen - 15;
 
 	if (fSmall)
@@ -377,18 +349,14 @@
 				else
 					sprintf(buf + strlen(buf), "%s%c",
 							get_sector_color(map[x][y].pRoom->sector_type),
-							map[x][y].symbol != '.' ? map[x][y].symbol : ' ');
+							map[x][y].symbol);
 			}
 			else
 			{
 				if (!fSmall)
-				{
-					strcat(buf, " ");
-					strcat(buf, &map[x][y].symbol);
-				}
+					strcat(buf, " .");
 				else
-					strcat(buf,
-						   map[x][y].symbol != '.' ? &map[x][y].symbol : " ");
+					strcat(buf, " ");
 			}
 		}
 		if (!fSmall)
@@ -508,7 +476,7 @@
 void draw_map(CHAR_DATA * ch, const char *desc)
 {
 	int x, y;
-	static char buf[MSL];
+	static char buf[MSL * 2];
 	bool fSmall;
 
 	if (IS_NULLSTR(desc))
@@ -516,7 +484,7 @@
 	else
 	{
 		fSmall = TRUE;
-		sprintf(buf, desc);
+		strcpy(buf, desc);
 
 		reformat_desc(buf);
 	}
@@ -534,9 +502,6 @@
 
 	depth = (fSmall) ? 2 : 0;
 
-	map[x][y].vnum = ch->in_room->vnum;
-	map[x][y].depth = depth;
-
 	map_exits(ch, ch->in_room, x, y);
 
 	map[x][y].symbol = 'X';
@@ -553,7 +518,7 @@
 			   "You no longer see automap room descriptions.");
 }
 
-bool check_blind args((CHAR_DATA * ch));
+PROTOTYPE(bool check_blind, (CHAR_DATA *));
 
 CH_CMD(do_map)
 {
diff -ur -x config -x o -x rom src/ban.c new/ban.c
--- src/ban.c	Tue May 27 02:46:35 2003
+++ new/ban.c	Sun Aug 31 19:23:20 2003
@@ -22,20 +22,136 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 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>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "recycle.h"
 #include "interp.h"
+#include "tablesave.h"
+
+/* The quoting character -- what overrides wildcards (do not undef)    */
+#define QUOTE '\\'
+
+/* The "matches ANYTHING" wildcard (do not undef)                      */
+#define WILDS '*'
+
+/* The "matches ANY NUMBER OF NON-SPACE CHARS" wildcard (do not undef) */
+#define WILDP '%'
+
+/* The "matches EXACTLY ONE CHARACTER" wildcard (do not undef)         */
+#define WILDQ '?'
+
+/* Changing these is probably counter-productive :) */
+#define MATCH (match+saved+sofar)
+#define NOMATCH 0
+
+int wild_match(register unsigned char *m, register unsigned char *n)
+{
+	unsigned char *ma = m, *lsm = 0, *lsn = 0, *lpm = 0, *lpn = 0;
+	int match = 1, saved = 0;
+	register unsigned int sofar = 0;
+
+	/* take care of null strings (should never match) */
+	if ((m == 0) || (n == 0) || (!*n))
+		return NOMATCH;
+
+	/* (!*m) test used to be here, too, but I got rid of it.  After all,
+	   If (!*n) was FALSE, there must be a character in the name (the
+	   second string), so if the mask is empty it is a non-match.  Since
+	   the algorithm handles this correctly without testing for it here
+	   and this shouldn't be called with null masks anyway, it should be
+	   a bit faster this way */
+
+	while (*n)
+	{
+		/* Used to test for (!*m) here, but this scheme seems to work better */
+		switch (*m)
+		{
+		case 0:
+			do
+				m--;			/* Search backwards      */
+			while ((m > ma) && (*m == '?'));	/* For first non-? char  */
+			if ((m > ma) ? ((*m == '*') && (m[-1] != QUOTE)) : (*m == '*'))
+				return MATCH;	/* nonquoted * = match   */
+			break;
+		case WILDP:
+			while (*(++m) == WILDP);	/* Zap redundant %s      */
+			if (*m != WILDS)
+			{					/* Don't both if next=*  */
+				if (*n != ' ')
+				{				/* WILDS can't match ' ' */
+					lpm = m;
+					lpn = n;	/* Save % fallback spot  */
+					saved += sofar;
+					sofar = 0;	/* And save tally count  */
+				}
+				continue;		/* Done with %           */
+			}
+			/* FALL THROUGH */
+		case WILDS:
+			do
+				m++;			/* Zap redundant wilds   */
+			while ((*m == WILDS) || (*m == WILDP));
+			lsm = m;
+			lsn = n;
+			lpm = 0;			/* Save * fallback spot  */
+			match += (saved + sofar);	/* Save tally count      */
+			saved = sofar = 0;
+			continue;			/* Done with *           */
+		case WILDQ:
+			m++;
+			n++;
+			continue;			/* Match one char        */
+		case QUOTE:
+			m++;				/* Handle quoting        */
+		}
+
+		if (tolower(*m) == tolower(*n))
+		{						/* If matching           */
+			m++;
+			n++;
+			sofar++;
+			continue;			/* Tally the match       */
+		}
+		if (lpm)
+		{						/* Try to fallback on %  */
+			n = ++lpn;
+			m = lpm;
+			sofar = 0;			/* Restore position      */
+			if ((*n | 32) == 32)
+				lpm = 0;		/* Can't match 0 or ' '  */
+			continue;			/* Next char, please     */
+		}
+		if (lsm)
+		{						/* Try to fallback on *  */
+			n = ++lsn;
+			m = lsm;			/* Restore position      */
+			/* Used to test for (!*n) here but it wasn't necessary so it's gone */
+			saved = sofar = 0;
+			continue;			/* Next char, please     */
+		}
+		return NOMATCH;			/* No fallbacks=No match */
+	}
+	while ((*m == WILDS) || (*m == WILDP))
+		m++;					/* Zap leftover %s & *s  */
+	return (*m) ? NOMATCH : MATCH;	/* End of both = match   */
+}
+
+BAN_DATA ban;
+
+const struct savetable_type bansavetable[] = {
+	{"name", FIELD_STRING, (void *) &ban.name, NULL, NULL},
+	{"level", FIELD_INT, (void *) &ban.level, NULL, NULL},
+	{"flags", FIELD_FLAGVECTOR, (void *) &ban.ban_flags, NULL, NULL},
+	{NULL, 0, NULL, NULL, NULL}
+};
+
+TABLESAVE(rw_bans)
+{
+	rw_list(type, BAN_FILE, BAN_DATA, ban_first, ban_last, next, prev, new_ban,
+			"BAN", ban, bansavetable);
+}
 
 bool check_ban(const char *site, int type)
 {
@@ -50,37 +166,24 @@
 		if (!IS_SET(pban->ban_flags, type))
 			continue;
 
-		if (IS_SET(pban->ban_flags, BAN_PREFIX) &&
-			IS_SET(pban->ban_flags, BAN_SUFFIX) &&
-			strstr(pban->name, host) != NULL)
-			return TRUE;
-
-		if (IS_SET(pban->ban_flags, BAN_PREFIX) &&
-			!str_suffix(pban->name, host))
-			return TRUE;
-
-		if (IS_SET(pban->ban_flags, BAN_SUFFIX) &&
-			!str_prefix(pban->name, host))
+		if (wild_match((unsigned char *) pban->name, (unsigned char *) host))
 			return TRUE;
 	}
 
 	return FALSE;
 }
 
-void ban_site(CHAR_DATA * ch, const char *argument, bool fPerm)
+void ban_site(CHAR_DATA * ch, const char *argument)
 {
-	char buf[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH];
 	char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
-	char *name;
 	BUFFER *buffer;
 	BAN_DATA *pban, *prev;
-	bool prefix = FALSE, suffix = FALSE;
 	int type;
 
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		if (ban_first == NULL)
 		{
@@ -89,29 +192,24 @@
 		}
 		buffer = new_buf();
 
-		add_buf(buffer, "Banned sites  level  type     status\n\r");
+		bprintln(buffer, "Banned sites  level  type");
 		for (pban = ban_first; pban != NULL; pban = pban->next)
 		{
-			sprintf(buf2, "%s%s%s",
-					IS_SET(pban->ban_flags, BAN_PREFIX) ? "*" : "",
-					pban->name, IS_SET(pban->ban_flags, BAN_SUFFIX) ? "*" : "");
-			sprintf(buf, "%-12s    %-3d  %-7s  %s\n\r", buf2,
-					pban->level, IS_SET(pban->ban_flags,
-										BAN_NEWBIES) ? "newbies" :
-					IS_SET(pban->ban_flags,
-						   BAN_PERMIT) ? "permit" :
-					IS_SET(pban->ban_flags, BAN_ALL) ? "all" : "",
-					IS_SET(pban->ban_flags, BAN_PERMANENT) ? "perm" : "temp");
-			add_buf(buffer, buf);
+			bprintlnf(buffer, "%-12s    %-3d  %s", pban->name,
+					  pban->level, IS_SET(pban->ban_flags,
+										  BAN_NEWBIES) ? "newbies" :
+					  IS_SET(pban->ban_flags,
+							 BAN_PERMIT) ? "permit" :
+					  IS_SET(pban->ban_flags, BAN_ALL) ? "all" : "");
 		}
 
-		page_to_char(buf_string(buffer), ch);
+		sendpage(ch, buf_string(buffer));
 		free_buf(buffer);
 		return;
 	}
 
 	/* find out what type of ban */
-	if (arg2[0] == '\0' || !str_prefix(arg2, "all"))
+	if (IS_NULLSTR(arg2) || !str_prefix(arg2, "all"))
 		type = BAN_ALL;
 	else if (!str_prefix(arg2, "newbies"))
 		type = BAN_NEWBIES;
@@ -123,21 +221,7 @@
 		return;
 	}
 
-	name = arg1;
-
-	if (name[0] == '*')
-	{
-		prefix = TRUE;
-		name++;
-	}
-
-	if (name[strlen(name) - 1] == '*')
-	{
-		suffix = TRUE;
-		name[strlen(name) - 1] = '\0';
-	}
-
-	if (strlen(name) == 0)
+	if (strlen(arg1) == 0)
 	{
 		chprintln(ch, "You have to ban SOMETHING.");
 		return;
@@ -148,11 +232,11 @@
 	{
 		prev = pban->next;
 
-		if (!str_cmp(name, pban->name))
+		if (!str_cmp(arg1, pban->name))
 		{
 			if (pban->level > get_trust(ch))
 			{
-				chprint(ch, "That ban was set by a higher power.");
+				chprintln(ch, "That ban was set by a higher power.");
 				return;
 			}
 			else
@@ -164,34 +248,21 @@
 	}
 
 	pban = new_ban();
-	pban->name = str_dup(name);
+	pban->name = str_dup(arg1);
 	pban->level = get_trust(ch);
 
 	/* set ban type */
 	pban->ban_flags = type;
 
-	if (prefix)
-		SET_BIT(pban->ban_flags, BAN_PREFIX);
-	if (suffix)
-		SET_BIT(pban->ban_flags, BAN_SUFFIX);
-	if (fPerm)
-		SET_BIT(pban->ban_flags, BAN_PERMANENT);
-
 	LINK(pban, ban_first, ban_last, next, prev);
-	save_bans();
-	sprintf(buf, "%s has been banned.\n\r", pban->name);
-	chprint(ch, buf);
+	rw_bans(action_write);
+	chprintlnf(ch, "%s has been banned.", pban->name);
 	return;
 }
 
 CH_CMD(do_ban)
 {
-	ban_site(ch, argument, FALSE);
-}
-
-CH_CMD(do_permban)
-{
-	ban_site(ch, argument, TRUE);
+	ban_site(ch, argument);
 }
 
 CH_CMD(do_allow)
@@ -202,7 +273,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Remove which site from the ban list?");
 		return;
@@ -224,7 +295,7 @@
 
 			free_ban(curr);
 			chprintlnf(ch, "Ban on %s lifted.", arg);
-			save_bans();
+			rw_bans(action_write);
 			return;
 		}
 	}
diff -ur -x config -x o -x rom src/bit.c new/bit.c
--- src/bit.c	Tue May 27 02:46:35 2003
+++ new/bit.c	Sun Aug 31 19:23:20 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /***************************************************************************
@@ -44,21 +44,10 @@
  implementing a system like below with such functions. -Jason Dinkel
  */
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "tables.h"
 #include "lookup.h"
 
-struct flag_stat_type
-{
-	const struct flag_type *structure;
-	bool stat;
-};
-
 /*****************************************************************************
  Name:		flag_stat_table
  Purpose:	This table catagorizes the tables following the lookup
@@ -66,46 +55,49 @@
  		but stats can only be assigned.  Update this table when a
  		new set of flags is installed.
  ****************************************************************************/
+#define STNM(flag)  #flag, flag
+
 const struct flag_stat_type flag_stat_table[] = {
 /*  {	structure		stat	}, */
-	{area_flags, FALSE},
-	{sex_flags, TRUE},
-	{exit_flags, FALSE},
-	{door_resets, TRUE},
-	{room_flags, FALSE},
-	{sector_flags, TRUE},
-	{type_flags, TRUE},
-	{extra_flags, FALSE},
-	{wear_flags, FALSE},
-	{act_flags, FALSE},
-	{plr_flags, FALSE},
-	{comm_flags, FALSE},
-	{affect_flags, FALSE},
-	{apply_flags, TRUE},
-	{wear_loc_flags, TRUE},
-	{wear_loc_strings, TRUE},
-	{container_flags, FALSE},
-	{mprog_flags, FALSE},
-	{rprog_flags, FALSE},
-	{oprog_flags, FALSE},
-	{info_flags, FALSE},
+	{STNM(area_flags), FALSE},
+	{STNM(sex_flags), TRUE},
+	{STNM(exit_flags), FALSE},
+	{STNM(door_resets), TRUE},
+	{STNM(room_flags), FALSE},
+	{STNM(sector_flags), TRUE},
+	{STNM(type_flags), TRUE},
+	{STNM(extra_flags), FALSE},
+	{STNM(wear_flags), FALSE},
+	{STNM(act_flags), FALSE},
+	{STNM(plr_flags), FALSE},
+	{STNM(comm_flags), FALSE},
+	{STNM(affect_flags), FALSE},
+	{STNM(apply_flags), TRUE},
+	{STNM(wear_loc_flags), TRUE},
+	{STNM(wear_loc_strings), TRUE},
+	{STNM(container_flags), FALSE},
+	{STNM(mprog_flags), FALSE},
+	{STNM(rprog_flags), FALSE},
+	{STNM(oprog_flags), FALSE},
+	{STNM(info_flags), FALSE},
 /* ROM specific flags: */
 
-	{form_flags, FALSE},
-	{part_flags, FALSE},
-	{ac_type, TRUE},
-	{size_flags, TRUE},
-	{position_flags, TRUE},
-	{off_flags, FALSE},
-	{imm_flags, FALSE},
-	{res_flags, FALSE},
-	{vuln_flags, FALSE},
-	{weapon_class, TRUE},
-	{weapon_type2, FALSE},
-	{apply_types, TRUE},
-	{desc_flags, FALSE},
-	{log_flags, TRUE},
-	{target_flags, TRUE},
+	{STNM(form_flags), FALSE},
+	{STNM(part_flags), FALSE},
+	{STNM(ac_type), TRUE},
+	{STNM(size_flags), TRUE},
+	{STNM(position_flags), TRUE},
+	{STNM(off_flags), FALSE},
+	{STNM(imm_flags), FALSE},
+	{STNM(res_flags), FALSE},
+	{STNM(vuln_flags), FALSE},
+	{STNM(weapon_class), TRUE},
+	{STNM(weapon_type2), FALSE},
+	{STNM(apply_types), TRUE},
+	{STNM(desc_flags), FALSE},
+	{STNM(log_flags), TRUE},
+	{STNM(target_flags), TRUE},
+	{STNM(chan_types), TRUE},
 	{0, 0}
 };
 
@@ -155,7 +147,7 @@
 		char word[MAX_INPUT_LENGTH];
 		argument = one_argument(argument, word);
 
-		if (word[0] == '\0')
+		if (IS_NULLSTR(word))
 			break;
 
 		if ((f = flag_lookup(word, flag_table)) != NULL)
Only in new: bits.h
diff -ur -x config -x o -x rom src/board.c new/board.c
--- src/board.c	Tue May 27 02:46:35 2003
+++ new/board.c	Sun Aug 31 19:23:20 2003
@@ -22,19 +22,14 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "recycle.h"
+#include "tables.h"
 
 /*
  
@@ -70,21 +65,25 @@
 
 BOARD_DATA boards[MAX_BOARD] = {
 
+	{"Announce", "Announcements from Immortals", 0, L_SUP, "all", DEF_NORMAL,
+	 60, NULL, NULL, FALSE}
+	,
 	{"General", "General discussion", 0, 2, "all", DEF_INCLUDE, 21, NULL, NULL,
 	 FALSE}
 	,
 	{"Ideas", "Suggestion for improvement", 0, 2, "all", DEF_NORMAL, 60, NULL, NULL,
 	 FALSE}
 	,
-	{"Announce", "Announcements from Immortals", 0, L_SUP, "all", DEF_NORMAL,
-	 60, NULL, NULL, FALSE}
-	,
 
 	{"Bugs", "Typos, bugs, errors", 0, 1, "imm", DEF_NORMAL, 60, NULL, NULL,
 	 FALSE}
 	,
 	{"Personal", "Personal messages", 0, 1, "all", DEF_EXCLUDE, 28, NULL, NULL,
 	 FALSE}
+	,
+
+	{"Immortal", "Immortals only", LEVEL_IMMORTAL, LEVEL_IMMORTAL, "imm",
+	 DEF_INCLUDE, 21, NULL, NULL, FALSE}
 
 };
 
@@ -101,7 +100,11 @@
 #define BOARD_NOACCESS -1
 #define BOARD_NOTFOUND -1
 
-static bool next_board(CHAR_DATA * ch);
+#undef EXTERN
+#define EXTERN
+PROTOTYPE(static bool next_board, (CHAR_DATA *));
+#undef EXTERN
+#define EXTERN EXTERN
 
 /* recycle a note */
 void free_note(NOTE_DATA * note)
@@ -125,13 +128,7 @@
 {
 	NOTE_DATA *note;
 
-	if (note_free)
-	{
-		note = note_free;
-		note_free = note_free->next;
-	}
-	else
-		alloc_mem(note, NOTE_DATA, 1);
+	GET_FREE(note, NOTE_DATA, next, note_free);
 
 	/* Zero all the field - Envy does not gurantee zeroed memory */
 	note->next = NULL;
@@ -161,7 +158,7 @@
 /* Save a note in a given board */
 void finish_note(BOARD_DATA * board, NOTE_DATA * note)
 {
-	FILE *fp;
+	WRITE_DATA *fp;
 	char filename[200];
 
 	/* The following is done in order to generate unique date_stamps */
@@ -180,16 +177,16 @@
 
 	sprintf(filename, "%s%s", NOTE_DIR, board->short_name);
 
-	fp = file_open(filename, "a");
+	fp = open_append(filename);
 	if (!fp)
 	{
-		bug("Could not open one of the note files in append mode", 0);
+		bug("Could not open one of the note files in append mode");
 		board->changed = TRUE;	/* set it to TRUE hope it will be OK later? */
 		return;
 	}
 
-	append_note(fp, note);
-	file_close(fp);
+	append_note(fp->stream, note);
+	close_append(fp);
 }
 
 /* Find the number of a board */
@@ -242,26 +239,26 @@
 /* save a single board */
 static void save_board(BOARD_DATA * board)
 {
-	FILE_DATA *fp;
+	WRITE_DATA *fp;
 	char filename[200];
 	char buf[200];
 	NOTE_DATA *note;
 
-	sprintf(filename, "%s/%s", NOTE_DIR, board->short_name);
+	sprintf(filename, "%s%s", NOTE_DIR, board->short_name);
 
-	fp = fopen_temp(filename);
+	fp = open_write(filename);
 
 	if (!fp)
 	{
 		sprintf(buf, "Error writing to: %s", filename);
-		bug(buf, 0);
+		bug(buf);
 	}
 	else
 	{
 		for (note = board->note_first; note; note = note->next)
-			append_note(fp->file, note);
+			append_note(fp->stream, note);
 
-		fclose_temp(fp);
+		close_write(fp);
 	}
 }
 
@@ -291,12 +288,13 @@
 /* Load a single board */
 static void load_board(BOARD_DATA * board)
 {
-	FILE *fp, *fp_archive;
+	READ_DATA *fp;
+	WRITE_DATA *fp_archive;
 	char filename[200];
 
-	sprintf(filename, "%s/%s", NOTE_DIR, board->short_name);
+	sprintf(filename, "%s%s", NOTE_DIR, board->short_name);
 
-	fp = file_open(filename, "r");
+	fp = open_read(filename);
 
 	/* Silently return */
 	if (!fp)
@@ -311,45 +309,44 @@
 
 		do
 		{
-			letter = getc(fp);
-			if (feof(fp))
+			if ((letter = read_letter(fp)) == NUL)
 			{
-				file_close(fp);
+				close_read(fp);
 				return;
 			}
 		}
 		while (isspace(letter));
-		ungetc(letter, fp);
+		fp->pos--;
 
 		alloc_mem(pnote, NOTE_DATA, 1);
 
-		if (str_cmp(fread_word(fp), "sender"))
+		if (str_cmp(read_word(fp), "sender"))
 			break;
-		pnote->sender = fread_string(fp);
+		pnote->sender = read_string(fp);
 
-		if (str_cmp(fread_word(fp), "date"))
+		if (str_cmp(read_word(fp), "date"))
 			break;
-		pnote->date = fread_string(fp);
+		pnote->date = read_string(fp);
 
-		if (str_cmp(fread_word(fp), "stamp"))
+		if (str_cmp(read_word(fp), "stamp"))
 			break;
-		pnote->date_stamp = fread_number(fp);
+		pnote->date_stamp = read_number(fp);
 
-		if (str_cmp(fread_word(fp), "expire"))
+		if (str_cmp(read_word(fp), "expire"))
 			break;
-		pnote->expire = fread_number(fp);
+		pnote->expire = read_number(fp);
 
-		if (str_cmp(fread_word(fp), "to"))
+		if (str_cmp(read_word(fp), "to"))
 			break;
-		pnote->to_list = fread_string(fp);
+		pnote->to_list = read_string(fp);
 
-		if (str_cmp(fread_word(fp), "subject"))
+		if (str_cmp(read_word(fp), "subject"))
 			break;
-		pnote->subject = fread_string(fp);
+		pnote->subject = read_string(fp);
 
-		if (str_cmp(fread_word(fp), "text"))
+		if (str_cmp(read_word(fp), "text"))
 			break;
-		pnote->text = fread_string(fp);
+		pnote->text = read_string(fp);
 
 		/* Should this note be archived right now ? */
 
@@ -358,13 +355,13 @@
 			char archive_name[200];
 
 			sprintf(archive_name, "%s%s.old", NOTE_DIR, board->short_name);
-			fp_archive = file_open(archive_name, "a");
+			fp_archive = open_append(archive_name);
 			if (!fp_archive)
-				bug("Could not open archive boards for writing", 0);
+				bug("Could not open archive boards for writing");
 			else
 			{
-				append_note(fp_archive, pnote);
-				file_close(fp_archive);	/* it might be more efficient to close this later */
+				append_note(fp_archive->stream, pnote);
+				close_append(fp_archive);	/* it might be more efficient to close this later */
 			}
 
 			free_note(pnote);
@@ -376,7 +373,7 @@
 		LINK(pnote, board->note_first, board->note_last, next, prev);
 	}
 
-	bug("Load_notes: bad key word.", 0);
+	bug("Load_notes: bad key word.");
 	return;						/* just return */
 }
 
@@ -395,6 +392,9 @@
 	if (!str_cmp(ch->name, note->sender))
 		return TRUE;
 
+	if (is_ignoring(ch, note->to_list, IGNORE_NOTES))
+		return FALSE;
+
 	if (is_full_name("all", note->to_list))
 		return TRUE;
 
@@ -421,6 +421,10 @@
 	if (is_number(note->to_list) && get_trust(ch) >= atoi(note->to_list))
 		return TRUE;
 
+	if (is_clan(ch) && (is_full_name(ch->clan->name, note->to_list)
+						|| is_full_name("clan", note->to_list)))
+		return TRUE;
+
 	return FALSE;
 }
 
@@ -477,10 +481,10 @@
 	if (!ch->pcdata->in_progress)
 	{
 		ch->pcdata->in_progress = new_note();
-		ch->pcdata->in_progress->sender = str_dup(ch->name);
+		replace_string(ch->pcdata->in_progress->sender, ch->name);
 
-		ch->pcdata->in_progress->date =
-			str_dup(str_time(current_time, -1, NULL));
+		replace_string(ch->pcdata->in_progress->date,
+					   str_time(current_time, -1, NULL));
 	}
 
 	act("{G$n starts writing a note.{x", ch, NULL, NULL, TO_ROOM);
@@ -860,13 +864,13 @@
 
 	if (board_index == BOARD_NOTFOUND)
 	{
-		bug("make_note: board not found", 0);
+		bug("make_note: board not found");
 		return;
 	}
 
 	if (strlen(text) > MAX_NOTE_TEXT)
 	{
-		bug("make_note: text too long (%d bytes)", strlen(text));
+		bugf("make_note: text too long (%d bytes)", strlen(text));
 		return;
 	}
 
@@ -911,7 +915,7 @@
 	if (!ch->pcdata->in_progress)
 	{
 		d->connected = CON_PLAYING;
-		bug("nanny: In CON_NOTE_TO, but no note in progress", 0);
+		bugf("nanny: In CON_NOTE_TO, but no note in progress");
 		return;
 	}
 
@@ -923,14 +927,13 @@
 	case DEF_NORMAL:			/* default field */
 		if (!buf[0])			/* empty string? */
 		{
-			ch->pcdata->in_progress->to_list =
-				str_dup(ch->pcdata->board->names);
-			sprintf(buf, "Assumed default recipient: {W%s{x\n\r",
-					ch->pcdata->board->names);
-			write_to_buffer(d, buf, 0);
+			replace_string(ch->pcdata->in_progress->to_list,
+						   ch->pcdata->board->names);
+			d_printlnf(d, "Assumed default recipient: {W%s{x",
+					   ch->pcdata->board->names);
 		}
 		else
-			ch->pcdata->in_progress->to_list = str_dup(buf);
+			replace_string(ch->pcdata->in_progress->to_list, buf);
 
 		break;
 
@@ -939,42 +942,38 @@
 		{
 			strcat(buf, " ");
 			strcat(buf, ch->pcdata->board->names);
-			ch->pcdata->in_progress->to_list = str_dup(buf);
+			replace_string(ch->pcdata->in_progress->to_list, buf);
 
-			sprintf(buf,
-					"\n\rYou did not specify %s as recipient, so it was automatically added.\n\r"
-					"{YNew To{x :  %s\n\r", ch->pcdata->board->names,
-					ch->pcdata->in_progress->to_list);
-			write_to_buffer(d, buf, 0);
+			d_printlnf(d,
+					   "\n\rYou did not specify %s as recipient, so it was automatically added.\n\r"
+					   "{YNew To{x :  %s", ch->pcdata->board->names,
+					   ch->pcdata->in_progress->to_list);
 		}
 		else
-			ch->pcdata->in_progress->to_list = str_dup(buf);
+			replace_string(ch->pcdata->in_progress->to_list, buf);
 		break;
 
 	case DEF_EXCLUDE:			/* forced exclude */
 		if (!buf[0])
 		{
-			write_to_buffer(d,
-							"You must specify a recipient.\n\r"
-							"{YTo{x:      ", 0);
+			d_print(d, "You must specify a recipient.\n\r" "{YTo{x:      ", 0);
 			return;
 		}
 
 		if (is_full_name(ch->pcdata->board->names, buf))
 		{
-			sprintf(buf,
-					"You are not allowed to send notes to %s on this board. Try again.\n\r"
-					"{YTo{x:      ", ch->pcdata->board->names);
-			write_to_buffer(d, buf, 0);
+			d_printf(d,
+					 "You are not allowed to send notes to %s on this board. Try again.\n\r"
+					 "{YTo{x:      ", ch->pcdata->board->names);
 			return;				/* return from nanny, not changing to the next state! */
 		}
 		else
-			ch->pcdata->in_progress->to_list = str_dup(buf);
+			replace_string(ch->pcdata->in_progress->to_list, buf);
 		break;
 
 	}
 
-	write_to_buffer(d, "{Y\n\rSubject{x: ", 0);
+	d_print(d, "{Y\n\rSubject{x: ", 0);
 	d->connected = CON_NOTE_SUBJECT;
 }
 
@@ -986,7 +985,7 @@
 	if (!ch->pcdata->in_progress)
 	{
 		d->connected = CON_PLAYING;
-		bug("nanny: In CON_NOTE_SUBJECT, but no note in progress", 0);
+		bugf("nanny: In CON_NOTE_SUBJECT, but no note in progress");
 		return;
 	}
 
@@ -997,41 +996,38 @@
 
 	if (!buf[0])
 	{
-		write_to_buffer(d, "Please find a meaningful subject!\n\r", 0);
-		write_to_buffer(d, "{YSubject{x: ", 0);
+		d_println(d, "Please find a meaningful subject!", 0);
+		d_print(d, "{YSubject{x: ", 0);
 	}
 	else if (strlen(buf) > 60)
 	{
-		write_to_buffer(d,
-						"No, no. This is just the Subject. You're note writing the note yet. Twit.\n\r",
-						0);
+		d_println(d,
+				  "No, no. This is just the Subject. You're note writing the note yet. Twit.",
+				  0);
 	}
 	else
 		/* advance to next stage */
 	{
-		ch->pcdata->in_progress->subject = str_dup(buf);
+		replace_string(ch->pcdata->in_progress->subject, buf);
 		if (IS_IMMORTAL(ch))	/* immortals get to choose number of expire days */
 		{
-			sprintf(buf,
-					"\n\rHow many days do you want this note to expire in?\n\r"
-					"Press Enter for default value for this board, {W%d{x days.\n\r"
-					"{YExpire{x:  ", ch->pcdata->board->purge_days);
-			write_to_buffer(d, buf, 0);
+			d_printf(d,
+					 "\n\rHow many days do you want this note to expire in?\n\r"
+					 "Press Enter for default value for this board, {W%d{x days.\n\r"
+					 "{YExpire{x:  ", ch->pcdata->board->purge_days);
 			d->connected = CON_NOTE_EXPIRE;
 		}
 		else
 		{
 			ch->pcdata->in_progress->expire =
 				current_time + ch->pcdata->board->purge_days * 24L * 3600L;
-			sprintf(buf, "This note will expire %s\n\r",
-					str_time(ch->pcdata->in_progress->expire, GET_TZONE(ch),
-							 NULL));
-			write_to_buffer(d, buf, 0);
-			sprintf(buf,
-					"\n\rEnter text. Type {W%cq{x or {W@{x on an empty line to end note, or {W%ch{x for help.\n\r"
-					"======================================================================\n\r\n\r",
-					STR_EDIT_KEY(ch), STR_EDIT_KEY(ch));
-			write_to_buffer(d, buf, 0);
+			d_printlnf(d, "This note will expire %s",
+					   str_time(ch->pcdata->in_progress->expire, GET_TZONE(ch),
+								NULL));
+			d_printlnf(d,
+					   "\n\rEnter text. Type {W%cq{x or {W@{x on an empty line to end note, or {W%ch{x for help.\n\r"
+					   "======================================================================\n\r",
+					   STR_EDIT_KEY(ch), STR_EDIT_KEY(ch));
 			d->connected = CON_NOTE_TEXT;
 		}
 	}
@@ -1047,7 +1043,7 @@
 	if (!ch->pcdata->in_progress)
 	{
 		d->connected = CON_PLAYING;
-		bug("nanny: In CON_NOTE_EXPIRE, but no note in progress", 0);
+		bugf("nanny: In CON_NOTE_EXPIRE, but no note in progress");
 		return;
 	}
 
@@ -1057,8 +1053,8 @@
 		days = ch->pcdata->board->purge_days;
 	else /* use this expire */ if (!is_number(buf))
 	{
-		write_to_buffer(d, "Write the number of days!\n\r", 0);
-		write_to_buffer(d, "{YExpire{x:  ", 0);
+		d_println(d, "Write the number of days!", 0);
+		d_print(d, "{YExpire{x:  ", 0);
 		return;
 	}
 	else
@@ -1066,10 +1062,10 @@
 		days = atoi(buf);
 		if (days <= 0)
 		{
-			write_to_buffer(d,
-							"This is a positive MUD. Use positive numbers only! :)\n\r",
-							0);
-			write_to_buffer(d, "{YExpire{x:  ", 0);
+			d_println(d,
+					  "This is a positive MUD. Use positive numbers only! :)",
+					  0);
+			d_print(d, "{YExpire{x:  ", 0);
 			return;
 		}
 	}
@@ -1078,24 +1074,23 @@
 
 	ch->pcdata->in_progress->expire = expire;
 
-	sprintf(buf,
-			"\n\rEnter text. Type {W%cq{x or {W@{x on an empty line to end note, or {W%ch{x for help.\n\r"
-			"======================================================================\n\r\n\r",
-			STR_EDIT_KEY(ch), STR_EDIT_KEY(ch));
-	write_to_buffer(d, buf, 0);
+	d_printlnf(d,
+			   "\n\rEnter text. Type {W%cq{x or {W@{x on an empty line to end note, or {W%ch{x for help.\n\r"
+			   "======================================================================\n\r",
+			   STR_EDIT_KEY(ch), STR_EDIT_KEY(ch));
 	d->connected = CON_NOTE_TEXT;
 }
 
 void handle_con_note_text(DESCRIPTOR_DATA * d, const char *argument)
 {
-	int action = 0;
+	strshow_t action;
 	CHAR_DATA *ch = d->character;
 	char buf[MAX_STRING_LENGTH];
 
 	if (!ch->pcdata->in_progress)
 	{
 		d->connected = CON_PLAYING;
-		bug("nanny: In CON_NOTE_TEXT, but no note in progress", 0);
+		bugf("nanny: In CON_NOTE_TEXT, but no note in progress");
 		return;
 	}
 
@@ -1104,8 +1099,7 @@
 	switch (action)
 	{
 	case STRING_END:
-		sprintf(buf, "\n\r%s", szFinishPrompt);
-		write_to_buffer(d, buf, 0);
+		d_printf(d, "\n\r%s", szFinishPrompt);
 		d->connected = CON_NOTE_FINISH;
 		return;
 	case STRING_FOUND:
@@ -1117,15 +1111,14 @@
 		if (ch->pcdata->in_progress->text)
 		{
 			strcpy(buf, ch->pcdata->in_progress->text);
-			free_string(ch->pcdata->in_progress->text);
-			ch->pcdata->in_progress->text = str_dup("");
+			replace_string(ch->pcdata->in_progress->text, "");
 		}
 		else
 			strcpy(buf, "");
 
 		if ((strlen(argument) + strlen(buf)) > MAX_NOTE_TEXT)
 		{
-			write_to_buffer(d, "Note too long, bailing out!\n\r", 0);
+			d_println(d, "Note too long, bailing out!", 0);
 			free_note(ch->pcdata->in_progress);
 			ch->pcdata->in_progress = NULL;
 			d->connected = CON_PLAYING;
@@ -1134,8 +1127,7 @@
 
 		strcat(buf, argument);
 		strcat(buf, "\n\r");
-		free_string(ch->pcdata->in_progress->text);
-		ch->pcdata->in_progress->text = str_dup(buf);
+		replace_string(ch->pcdata->in_progress->text, buf);
 		return;
 	}
 }
@@ -1148,32 +1140,31 @@
 	if (!ch->pcdata->in_progress)
 	{
 		d->connected = CON_PLAYING;
-		bug("nanny: In CON_NOTE_FINISH, but no note in progress", 0);
+		bugf("nanny: In CON_NOTE_FINISH, but no note in progress");
 		return;
 	}
 
 	switch (tolower(argument[0]))
 	{
 	case 'c':					/* keep writing */
-		write_to_buffer(d, "Continuing note...\n\r", 0);
+		d_println(d, "Continuing note...", 0);
 		d->connected = CON_NOTE_TEXT;
 		break;
 
 	case 'v':					/* view note so far */
 		if (ch->pcdata->in_progress->text)
 		{
-			write_to_buffer(d, "{gText of your note so far:{x\n\r", 0);
-			write_to_buffer(d, ch->pcdata->in_progress->text, 0);
+			d_println(d, "{gText of your note so far:{x", 0);
+			d_print(d, ch->pcdata->in_progress->text, 0);
 		}
 		else
-			write_to_buffer(d, "You haven't written a thing!\n\r\n\r", 0);
-		write_to_buffer(d, szFinishPrompt, 0);
-		write_to_buffer(d, "\n\r", 0);
+			d_println(d, "You haven't written a thing!\n\r", 0);
+		d_println(d, szFinishPrompt, 0);
 		break;
 
 	case 'p':					/* post note */
 		finish_note(ch->pcdata->board, ch->pcdata->in_progress);
-		write_to_buffer(d, "Note posted.\n\r", 0);
+		d_println(d, "Note posted.", 0);
 		d->connected = CON_PLAYING;
 		announce(ch, INFO_NOTE,
 				 "You have a new note on the %s board from $n",
@@ -1184,7 +1175,7 @@
 		break;
 
 	case 'f':
-		write_to_buffer(d, "Note cancelled!\n\r", 0);
+		d_println(d, "Note cancelled!", 0);
 		free_note(ch->pcdata->in_progress);
 		ch->pcdata->in_progress = NULL;
 		d->connected = CON_PLAYING;
@@ -1192,9 +1183,7 @@
 		break;
 
 	default:					/* invalid response */
-		write_to_buffer(d, "Huh? Valid answers are:\n\r\n\r", 0);
-		write_to_buffer(d, szFinishPrompt, 0);
-		write_to_buffer(d, "\n\r", 0);
-
+		d_println(d, "Huh? Valid answers are:\n\r", 0);
+		d_println(d, szFinishPrompt, 0);
 	}
 }
diff -ur -x config -x o -x rom src/board.h new/board.h
--- src/board.h	Tue May 27 02:46:36 2003
+++ new/board.h	Sun Aug 31 19:23:21 2003
@@ -22,19 +22,17 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /* Includes for board system */
 /* This is version 2 of the board system, (c) 1995-96 erwin@andreasen.org */
 
-#define NOTE_DIR  				"../notes/"	/* set it to something you like */
-
 #define DEF_NORMAL  0			/* No forced change, but default (any string)   */
 #define DEF_INCLUDE 1			/* 'names' MUST be included (only ONE name!)    */
 #define DEF_EXCLUDE 2			/* 'names' must NOT be included (one name only) */
 
-#define MAX_BOARD 	  5
+#define MAX_BOARD 	  6
 
 #define DEFAULT_BOARD 0			/* default board is board #0 in the boards      */
 			/* It should be readable by everyone!           */
@@ -72,25 +70,4 @@
 
 /* External variables */
 
-extern BOARD_DATA boards[MAX_BOARD];	/* Declare */
-
-/* Prototypes */
-
-void finish_note(BOARD_DATA * board, NOTE_DATA * note);	/* attach a note to a board */
-void free_note(NOTE_DATA * note);	/* deallocate memory used by a note */
-void load_boards(void);			/* load all boards */
-int board_lookup(const char *name);	/* Find a board with that name */
-bool is_note_to(CHAR_DATA * ch, NOTE_DATA * note);	/* is tha note to ch? */
-void personal_message(const char *sender, const char *to,
-					  const char *subject, const int expire_days,
-					  const char *text);
-void make_note(const char *board_name, const char *sender, const char *to,
-			   const char *subject, const int expire_days, const char *text);
-void save_notes();
-
-/* for nanny */
-void handle_con_note_to(DESCRIPTOR_DATA * d, const char *argument);
-void handle_con_note_subject(DESCRIPTOR_DATA * d, const char *argument);
-void handle_con_note_expire(DESCRIPTOR_DATA * d, const char *argument);
-void handle_con_note_text(DESCRIPTOR_DATA * d, const char *argument);
-void handle_con_note_finish(DESCRIPTOR_DATA * d, const char *argument);
+EXTERN BOARD_DATA boards[MAX_BOARD];	/* Declare */
diff -ur -x config -x o -x rom src/buddy.c new/buddy.c
--- src/buddy.c	Tue May 27 02:46:35 2003
+++ new/buddy.c	Sun Aug 31 19:23:20 2003
@@ -22,28 +22,22 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 #include "merc.h"
+#include "gcn.h"
 
 CH_CMD(do_btalk)
 {
 	if (!ch || IS_NPC(ch))
 		return;
 
-	public_ch(ch, argument,
-			  "{W{{" CTAG(_BTALK1) "Buddy{W}" CTAG(_BTALK2), COMM_NOBUDDY,
-			  spec_buddy_flag, LAST_BTALK);
+	public_ch(ch, argument, gcn_buddy);
 	return;
 }
 
-void buddy_offline args((CHAR_DATA * ch, char *arg, int pos));
+PROTOTYPE(void buddy_offline, (CHAR_DATA *, char *, int));
 
 CH_CMD(do_buddy)
 {
@@ -189,15 +183,7 @@
 
 void buddy_offline(CHAR_DATA * ch, char *arg, int pos)
 {
-	char buf[MIL];
-	FILE *fp;
-	bool exists;
-
-	sprintf(buf, "%s%s", PLAYER_DIR, capitalize(arg));
-	exists = ((fp = file_open(buf, "r")) != NULL) ? TRUE : FALSE;
-	file_close(fp);
-
-	if (!exists)
+	if (!file_exists("%s%s", PLAYER_DIR, capitalize(arg)))
 	{
 		chprintln(ch, "That character doesn't exist.");
 		return;
Only in new: channels.c
diff -ur -x config -x o -x rom src/clans.c new/clans.c
--- src/clans.c	Tue May 27 02:46:35 2003
+++ new/clans.c	Sun Aug 31 19:23:20 2003
@@ -22,22 +22,48 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "interp.h"
 #include "lookup.h"
 #include "tables.h"
 #include "recycle.h"
+#include "tablesave.h"
+
+CLAN_DATA clan;
+MBR_DATA mbr;
+
+const struct savetable_type mbrsavetable[] = {
+	{"name", FIELD_STRING, (void *) &mbr.name, NULL, NULL},
+	{"clan", FIELD_FUNCTION_INT_TO_STR, (void *) &mbr.clan, (void *) clan_rw,
+	 NULL},
+	{"rank", FIELD_INT, (void *) &mbr.rank, NULL, NULL},
+	{"level", FIELD_INT, (void *) &mbr.level, NULL, NULL},
+	{NULL, 0, NULL, NULL, NULL}
+};
+
+const struct savetable_type clansavetable[] = {
+	{"name", FIELD_STRING, (void *) &clan.name, NULL, NULL},
+	{"whoname", FIELD_STRING, (void *) &clan.who_name, NULL, NULL},
+	{"hall", FIELD_LONG, (void *) &clan.hall, NULL, NULL},
+	{"indep", FIELD_BOOL, (void *) &clan.independent, NULL, NULL},
+	{"rank", FIELD_RANK_DATA, (void *) &clan.rank, (void *) MAX_RANK, NULL},
+	{NULL, 0, NULL, NULL, NULL}
+};
+
+TABLESAVE(rw_members)
+{
+	rw_list(type, MBR_FILE, MBR_DATA, mbr_first, mbr_last, next, prev, new_mbr,
+			"MBR", mbr, mbrsavetable);
+}
+
+TABLESAVE(rw_clans)
+{
+	rw_list(type, CLAN_FILE, CLAN_DATA, clan_first, clan_last, next, prev,
+			new_clan, "CLAN", clan, clansavetable);
+}
 
 bool is_leader(CHAR_DATA * ch)
 {
@@ -158,7 +184,7 @@
 	int r;
 	CLAN_DATA *i;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Syntax: cinfo <clan name>");
 		return;
@@ -518,7 +544,7 @@
 			UNLINK(curr, mbr_first, mbr_last, next, prev);
 
 			free_mbr(curr);
-			save_members();
+			rw_members(action_write);
 		}
 	}
 	if (pdelete || !is_clan(ch) || ch->clan->independent)
@@ -530,7 +556,7 @@
 	curr->clan = ch->clan;
 	curr->level = ch->level;
 	LINK(curr, mbr_first, mbr_last, next, prev);
-	save_members();
+	rw_members(action_write);
 	return;
 }
 
@@ -568,7 +594,7 @@
 				UNLINK(curr, mbr_first, mbr_last, next, prev);
 
 				free_mbr(curr);
-				save_members();
+				rw_members(action_write);
 				found = TRUE;
 			}
 		}
Only in new: client.c
diff -ur -x config -x o -x rom src/comm.c new/comm.c
--- src/comm.c	Tue May 27 02:46:35 2003
+++ new/comm.c	Sun Aug 31 19:23:20 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
@@ -35,360 +35,284 @@
  *    Game_loop ---> Read_from_buffer
  *
  * The data flow for output is:
- *    Game_loop ---> Process_Output ---> Write_to_descriptor -> Write
+ *    Game_loop ---> Process_Output ---> d_write -> Write
  *
- * The OS-dependent functions are Read_from_descriptor and Write_to_descriptor.
+ * The OS-dependent functions are Read_from_descriptor and d_write.
  * -- Furey  26 Jan 1993
  */
-
-#if !defined(_GNU_SOURCE)
-#define _GNU_SOURCE
-#endif
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <unistd.h>				/* OLC -- for close read write etc */
-#else
-#include <winsock2.h>
-#include <sys\timeb.h>
-#include <direct.h>
-#include <io.h>
-#endif
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <stdarg.h>				/* chprintf */
 #include "merc.h"
 #include "interp.h"
 #include "recycle.h"
 #include "tables.h"
-#if defined(WIN32)
-#include "../win32/winstuff.h"
-#endif
 #include "webserver.h"
-
-#include <signal.h>
-
-#include <fcntl.h>
-#if !defined(WIN32)
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#endif
+#include "olc.h"
 #include "telnet.h"
+#include "tablesave.h"
+#include "signals.h"
 
 /*
  * Global variables.
  */
 DESCRIPTOR_DATA *d_next;		/* Next descriptor in loop  */
 bool god;						/* All new chars are gods!  */
-bool merc_down;					/* Shutdown         */
-char str_boot_time[MAX_INPUT_LENGTH];
-/* Needs to be global because of do_copyover */
-int control;
-/* Global variable */
-#if defined(WIN32) || defined(__CYGWIN__)
-#define NO_VTIMER
-#else
-struct itimerval vtimer;
-#endif
 
 #if	defined( WIN32 )
 #define WOULD_HAVE_BLOCKED ( WSAGetLastError() == WSAEWOULDBLOCK )
 #else
 #define WOULD_HAVE_BLOCKED ( errno == EWOULDBLOCK )
-volatile sig_atomic_t crashed = 0;	/* Are we currently crashing? */
-void halt_mud args((int sig));
-void set_shutdown args((bool down));
 #endif
 
-void game_loop args((int ctrl));
-int init_socket args((int prt));
-void init_descriptor args((int ctrl));
-bool read_from_descriptor args((DESCRIPTOR_DATA * d));
+PROTOTYPE(void game_loop, (int));
+PROTOTYPE(int init_socket, (int));
+PROTOTYPE(void init_descriptor, (int));
 
 /*
  * Other local functions (OS-independent).
  */
-int main args((int argc, char **argv));
-void nanny args((DESCRIPTOR_DATA * d, const char *argument));
-bool process_output args((DESCRIPTOR_DATA * d, bool fPrompt));
-void read_from_buffer args((DESCRIPTOR_DATA * d));
-void stop_idling args((CHAR_DATA * ch));
-void bust_a_prompt args((CHAR_DATA * ch));
-void set_game_levels args((int Old, int New));
-void save_helps args((void));
+PROTOTYPE(int main, (int, char **));
+PROTOTYPE(void nanny, (DESCRIPTOR_DATA *, const char *));
+PROTOTYPE(bool process_output, (DESCRIPTOR_DATA *, bool));
+PROTOTYPE(void read_from_buffer, (DESCRIPTOR_DATA *));
+PROTOTYPE(void stop_idling, (CHAR_DATA *));
+PROTOTYPE(void bust_a_prompt, (CHAR_DATA *));
+PROTOTYPE(void set_game_levels, (int, int));
+PROTOTYPE(void save_helps, (void));
+PROTOTYPE(int count_mxp_tags, (DESCRIPTOR_DATA *, const char *, int));
+PROTOTYPE(void convert_mxp_tags, (DESCRIPTOR_DATA *, char *, const char *,
+								  int));
+PROTOTYPE(bool check_directories, (void));
 
-void set_vtimer(long sec)
+#if defined(WIN32)
+void gettimeofday(struct timeval *t, void *tz)
 {
-#if !defined(NO_VTIMER)
-	vtimer.it_value.tv_sec = sec < 0 ? (60 * 3) : sec;
-	vtimer.it_value.tv_usec = 0;
-
-	if (setitimer(ITIMER_VIRTUAL, &vtimer, NULL) < 0)
-	{
-		log_string("Failed to set vtimer.");
-		exit(1);
-	}
-#endif
+	struct timeb timebuffer;
+	ftime(&timebuffer);
+	t->tv_sec = timebuffer.time;
+	t->tv_usec = timebuffer.millitm * 1000;
 }
+#endif
 
-#if !defined(WIN32)
-
-void sigvalarm(int sig)
+const char *whoami(void)
 {
-#if !defined(NO_VTIMER)
-	static int safe_check = 0;
-	char crash_message_a[] =
-		"The mud has been looping for the past 60 seconds.";
-	char crash_message_b[] = "Initiating reboot...";
-	char crash_message_c[] =
-		"The mud failed to inform the players of the above.";
-
-	switch (safe_check)
-	{
-	case 0:
-		safe_check = 1;
-		bug(crash_message_a, 0);
-		bug(crash_message_b, 0);
-		break;
-
-	case 1:
-		safe_check = 2;
-		log_string(crash_message_a);
-		log_string(crash_message_b);
-		log_string(crash_message_c);
-		break;
+#if defined(WIN32)
+	static char username[UNLEN + 1];
+	unsigned long szusername = UNLEN + 1;
 
-	case 2:
-		break;
+	if (GetUserName(username, &szusername))
+	{
+		return (username);
 	}
 
-	/* Reboot the MUD */
-
-	set_vtimer(-1);
-
-	halt_mud(sig);				// Shouldn't return
-
-	exit(1);					// Last resort
 #else
-	static int attempt = 0;
-	time_t ptm;
+	struct passwd *pwd;
+	uid_t uid;
 
-	time(&ptm);
-	log_string("TOCK!");
+	uid = getuid();
 
-	if ((ptm - current_time) > 120 || crashed)
+	if ((pwd = getpwuid(uid)))
 	{
-		if (attempt != 1)
-		{
-			attempt = 1;
-			halt_mud(sig);		// Should NOT return
-		}
-		raise(SIGSEGV);			// Something's wrong, cause a crash
-		exit(0);
+		return (pwd->pw_name);
 	}
-	alarm(60);
 #endif
+	return "unknown";
 }
 
-struct sigaction halt_action, ignore_action, valarm_action;
+bool verbose_log = FALSE;
 
-struct signal_type
+void cycle_log(void)
 {
-	int signum;
-	struct sigaction *act;
-	const char *name;			// not used, strsignal() prefered.
-	const char *desc;			// not used, strsignal() prefered.
-};
+	char buf[1024];
+	FILE *fp;
 
-const struct signal_type signal_table[] = {
-
-	{SIGPIPE, &ignore_action, "SIGPIPE",
-	 "Broken pipe: write to pipe with no readers"},
-	{SIGCHLD, &ignore_action, "SIGCHLD", "Child stopped or terminated"},
-
-	{SIGHUP, &ignore_action, "SIGHUP",
-	 "Hangup detected on controlling terminal or death of controlling process"},
-	{SIGINT, &halt_action, "SIGINT", "Interrupt from keyboard"},
-	{SIGQUIT, &halt_action, "SIGQUIT", "Quit from keyboard"},
-	{SIGILL, &halt_action, "SIGILL", "Illegal Instruction"},
-	{SIGFPE, &halt_action, "SIGFPE", "Floating point exception"},
-	{SIGSEGV, &halt_action, "SIGSEGV", "Invalid memory reference"},
-	{SIGTERM, &halt_action, "SIGTERM", "Termination signal"},
-	{SIGBUS, &halt_action, "SIGBUS", "Bus error (bad memory access)"},
-#if !defined(NO_VTIMER)
-	{SIGVTALRM, &valarm_action, "SIGVTALRM", "Virtual alarm clock"},
-#else
-	{SIGALRM, &valarm_action, "SIGALRM", "Timer signal from alarm(2)"},
-#endif
-	{-1, NULL, NULL, NULL}
-};
-
-void set_signals(void)
-{
-	int i;
-
-	halt_action.sa_handler = halt_mud;
-	sigemptyset(&halt_action.sa_mask);
-	halt_action.sa_flags = SA_NODEFER;
-
-	ignore_action.sa_handler = SIG_IGN;
-	sigemptyset(&ignore_action.sa_mask);
-	ignore_action.sa_flags = 0;
-
-	valarm_action.sa_handler = sigvalarm;
-	sigemptyset(&valarm_action.sa_mask);
-	valarm_action.sa_flags = SA_NODEFER;
-
-	for (i = 0; signal_table[i].signum != -1; i++)
-		sigaction(signal_table[i].signum, signal_table[i].act, NULL);
-
-#if !defined(NO_VTIMER)
-	vtimer.it_interval.tv_sec = 60;
-	vtimer.it_interval.tv_usec = 0;
-	set_vtimer(-1);
-#else
-	alarm(60);
-#endif
-}
-
-#else
-void gettimeofday(struct timeval *t, void *tz)
-{
-	struct timeb timebuffer;
-	ftime(&timebuffer);
-	t->tv_sec = timebuffer.time;
-	t->tv_usec = timebuffer.millitm * 1000;
+	sprintf(buf, "%s%s", LOG_DIR, str_time(-1, -1, "%m-%d.log"));
+	fp = file_open(buf, "a");
+	if (!fp)
+		log_error(buf);
+	else
+	{
+		if (!verbose_log)
+		{
+			dup2(fileno(fp), STDERR_FILENO);
+		}
+	}
+	file_close(fp);
 }
-#endif
 
 int main(int argc, char **argv)
 {
 	struct timeval now_time;
-#if !defined(WIN32)
-#if !defined(__CYGWIN__)
+#if !defined(NO_COPYOVER)
 	bool fCopyOver = FALSE;
 #endif
-
-	set_signals();
-#endif
+	int pos;
+	char **args = argv;
 
 	/*
 	 * Init time.
 	 */
+	run_level = RUNLEVEL_INIT;
 	tzset();
 	gettimeofday(&now_time, NULL);
 	current_time = (time_t) now_time.tv_sec;
-	strcpy(str_boot_time, str_time(current_time, -1, NULL));
-
-	if (gethostname(HOSTNAME, 1024) == -1)
-		perror("gethostname");
-	if (HOSTNAME[0] == '\0')
-		strcpy(HOSTNAME, "localhost");
+	boot_time = current_time;
 
 	/*
 	 * Reserve one channel for our use.
 	 */
 	if ((fpReserve = fopen(NULL_FILE, "r")) == NULL)
 	{
-		perror(NULL_FILE);
+		log_error(NULL_FILE);
 		exit(1);
 	}
 
+#if defined(WIN32)
+	{
+		/* Initialise Windows sockets library */
+
+		WORD wVersionRequested = MAKEWORD(2, 0);
+		WSADATA wsadata;
+
+		/* Need to include library: ws2_32.lib for Windows Sockets */
+		if (WSAStartup(wVersionRequested, &wsadata))
+		{
+			log_string("Couldn't initialize winsock.");
+			exit(1);
+		}
+	}
+#endif
+
+	if (gethostname(HOSTNAME, 1024) == -1 || IS_NULLSTR(HOSTNAME))
+		strcpy(HOSTNAME, "localhost");
+
+	if (!getcwd(CWDIR, 1024))
+		strcpy(CWDIR, AREA_DIR);
+
+	strcpy(UNAME, whoami());
+
+	strcpy(EXE_FILE, argv[0]);
+
 	/*
 	 * Get the port number.
 	 */
-	port = 4000;
-	if (argc > 1)
+	for (pos = 1; pos < argc; pos++)
 	{
-		if (!str_cmp(argv[1], "levels"))
+		bool option = FALSE;
+
+		if (IS_NULLSTR(args[pos]))
+			break;
+
+		if (*args[pos] == '-')
+		{
+			args[pos]++;
+			if (*args[pos] == '-')
+				args[pos]++;
+
+			if (*args[pos] != '-')
+				option = TRUE;
+		}
+
+		if (option)
 		{
-			if (IS_NULLSTR(argv[2]) || IS_NULLSTR(argv[3])
-				|| !is_number(argv[2]) || !is_number(argv[3]))
+			if (!str_cmp(args[pos], "v"))
+			{
+				verbose_log = TRUE;
+				log_string("Logging to stderr...");
+			}
+			else if (!str_cmp(args[pos], "version"))
+			{
+				log_string(MUD_NAME ": Compiled on " __DATE__ " at " __TIME__
+						   ".");
+				exit(0);
+			}
+#if !defined(NO_COPYOVER)
+			else if (!str_cmp(args[pos], "c"))
+			{
+				fCopyOver = TRUE;
+				control = atoi(args[++pos]);
+			}
+#endif
+			else if (!str_cmp(args[pos], "levels"))
+			{
+				int oldlev, newlev;
+
+				if (IS_NULLSTR(args[++pos])
+					|| !is_number(args[pos])
+					|| (oldlev = atoi(args[pos])) <= 0
+					|| IS_NULLSTR(args[++pos])
+					|| !is_number(args[pos]) || (newlev = atoi(args[pos])) <= 0)
+				{
+					logf("Usage: %s -levels [old max level] [new max level]",
+						 argv[0]);
+					exit(1);
+				}
+
+				boot_db();
+				set_game_levels(oldlev, newlev);
+				exit(0);
+			}
+			else
 			{
-				logf("Usage: %s levels [old max level] [new max level]",
+				if (args[pos][0] != '?')
+					logf("Invalid option '%s'.", args[pos]);
+				logf("Valid options: %s -version (displays info)", argv[0]);
+				logf("             : %s -v (disables log file)", argv[0]);
+				logf
+					("             : %s -levels [old max] [new max] (relevel the game)",
 					 argv[0]);
+
 				exit(1);
 			}
-
-			boot_db();
-			set_game_levels(atoi(argv[2]), atoi(argv[3]));
-			exit(0);
 		}
-		else if (!is_number(argv[1]))
+		else if (!IS_NULLSTR(args[pos]) && is_number(args[pos]))
 		{
-			logf("Usage: %s [port #]\n", argv[0]);
-			exit(1);
+			if ((port = atoi(args[pos])) <= 1024)
+			{
+				log_string("Port number must be above 1024.");
+				exit(1);
+			}
 		}
-		else if ((port = atoi(argv[1])) <= 1024)
+		else
 		{
-			logf("Port number must be above 1024.\n");
+			logf("Invalid argument '%s'.", args[pos]);
+			logf("Syntax: %s <port>", argv[0]);
 			exit(1);
 		}
-#if !defined(WIN32) && !defined(__CYGWIN__)
-		/* Are we recovering from a copyover? */
-		if (argv[2] && argv[2][0])
-		{
-			fCopyOver = TRUE;
-			control = atoi(argv[3]);
-		}
-		else
-			fCopyOver = FALSE;
-#endif
 	}
-
-#if defined(WIN32)
+	// do directory layout checks
+	if (check_directories())
 	{
-		/* Initialise Windows sockets library */
-
-		unsigned short wVersionRequested = MAKEWORD(1, 1);
-		WSADATA wsadata;
-		int err;
-
-		/* Need to include library: wsock32.lib for Windows Sockets */
-		err = WSAStartup(wVersionRequested, &wsadata);
-		if (err)
-		{
-			logf("Error %i on WSAStartup\n", err);
-			exit(1);
-		}
+		log_string("There may have been problems creating the directories...");
+		log_string("create them manually then try again.");
+		exit(1);
 	}
-#endif
+
+	cycle_log();
 
 	/*
 	 * Run the game.
 	 */
-#if !defined(WIN32) && !defined(__CYGWIN__)
+#if !defined(NO_COPYOVER)
 	if (!fCopyOver)
 #endif
 		control = init_socket(port);
 #if !defined(NO_WEB)
 	WebUP = init_web_server();
 #endif
+	log_string("Starting up " MUD_NAME "...");
 	boot_db();
-	sprintf(log_buf, "ROM is ready to rock on port %d.", port);
-	log_string(log_buf);
-#if !defined(WIN32) && !defined(__CYGWIN__)
+	set_signals();
+	logf(MUD_NAME " is ready to rock on port %d.", port);
+#if !defined(NO_COPYOVER)
 	if (fCopyOver)
 		copyover_recover();
 #endif
 	game_loop(control);
-#if !defined(NO_WEB)
-	if (WebUP)
-		shutdown_web_server();
-#endif
 	close(control);
-
 	/*
 	 * That's all, folks.
 	 */
 	log_string("Normal termination of game.");
-	exit(0);
+	exit(0);					// atexit will cleanup the mud hopefully
 	return 0;
 }
 
@@ -401,13 +325,13 @@
 
 	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
 	{
-		perror("Init_socket: socket");
+		log_error("Init_socket: socket");
 		exit(-1);
 	}
 
 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &x, sizeof(x)) < 0)
 	{
-		perror("Init_socket: SO_REUSEADDR");
+		log_error("Init_socket: SO_REUSEADDR");
 		close(fd);
 		exit(-1);
 	}
@@ -422,7 +346,7 @@
 		if (setsockopt
 			(fd, SOL_SOCKET, SO_DONTLINGER, (char *) &ld, sizeof(ld)) < 0)
 		{
-			perror("Init_socket: SO_DONTLINGER");
+			log_error("Init_socket: SO_DONTLINGER");
 			close(fd);
 			exit(-1);
 		}
@@ -435,14 +359,14 @@
 
 	if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
 	{
-		perror("Init socket: bind");
+		log_error("Init socket: bind");
 		close(fd);
 		exit(-1);
 	}
 
 	if (listen(fd, 3) < 0)
 	{
-		perror("Init socket: listen");
+		log_error("Init socket: listen");
 		close(fd);
 		exit(-1);
 	}
@@ -452,11 +376,10 @@
 
 void show_greeting(DESCRIPTOR_DATA * dnew)
 {
-	extern const char *help_greeting;
 	if (help_greeting[0] == '.')
-		write_to_buffer(dnew, help_greeting + 1, 0);
+		d_print(dnew, help_greeting + 1, 0);
 	else
-		write_to_buffer(dnew, help_greeting, 0);
+		d_print(dnew, help_greeting, 0);
 }
 
 #define MS_PER_PULSE ( 1000 / PULSE_PER_SECOND )
@@ -491,19 +414,18 @@
 		switch (errno)
 		{
 		case EBADF:
-			bug("Invalid file descriptor passed to Select()", 0);
+			bug("Invalid file descriptor passed to Select()");
 			break;
 		case EINTR:			//bugf("A non-blocked signal was caught.", 0);
 			break;
 		case EINVAL:
-			bug("Negative \'n\' descriptor passed to Select()", 0);
+			bug("Negative \'n\' descriptor passed to Select()");
 			break;
 		case ENOMEM:
-			bug("Select() was unable to allocate memory for internal tables.",
-				0);
+			bug("Select() was unable to allocate memory for internal tables.");
 			break;
 		default:
-			bug("Unknown error.", 0);
+			bug("Unknown error.");
 			break;
 		}
 	}
@@ -547,8 +469,10 @@
 
 	SynchronizeClock();
 
+	run_level = RUNLEVEL_MAIN_LOOP;
+
 	/* Main loop */
-	while (!merc_down)
+	while (run_level == RUNLEVEL_MAIN_LOOP)
 	{
 		fd_set in_set;
 		fd_set out_set;
@@ -576,7 +500,7 @@
 		{
 			if (errno != EINTR)
 			{
-				perror("Game_loop: select: poll");
+				log_error("Game_loop: select: poll");
 				exit(1);
 			}
 		}
@@ -637,7 +561,7 @@
 			}
 
 			read_from_buffer(d);
-			if (d->incomm[0] != '\0')
+			if (!IS_NULLSTR(d->incomm))
 			{
 				d->fcommand = TRUE;
 				stop_idling(d->character);
@@ -719,6 +643,8 @@
 		 */
 		WaitForPulse();
 		SynchronizeClock();
+		if (current_time % (HOUR) == 0)
+			cycle_log();
 #if !defined(NO_VTIMER)
 		if (++vt_set >= 35)
 		{
@@ -734,16 +660,11 @@
 
 void init_descriptor(int ctrl)
 {
-	char buf[MAX_STRING_LENGTH];
 	DESCRIPTOR_DATA *dnew;
 	struct sockaddr_in sock;
 	struct hostent *from;
 	int desc;
-#if defined(__CYGWIN__)
-	int size;
-#else
-	unsigned int size;
-#endif
+	socklen_t size;
 #if defined(WIN32)
 	static unsigned long ARGP = 1;
 #endif
@@ -754,7 +675,7 @@
 
 	if ((desc = accept(ctrl, (struct sockaddr *) &sock, &size)) < 0)
 	{
-		perror("New_descriptor: accept");
+		log_error("New_descriptor: accept");
 		return;
 	}
 
@@ -763,20 +684,19 @@
 #endif
 
 #if defined( WIN32 )
-
 	if (ioctlsocket(desc, FIONBIO, &ARGP) != 0)
 	{
 		bugf("ioctlsocket returned error code %d", WSAGetLastError());
 		return;
 	}
 #else
-
 	if (fcntl(desc, F_SETFL, FNDELAY) == -1)
 	{
-		perror("New_descriptor: fcntl: FNDELAY");
+		log_error("New_descriptor: fcntl: FNDELAY");
 		return;
 	}
 #endif
+
 	/*
 	 * Cons a new descriptor.
 	 */
@@ -786,7 +706,7 @@
 	size = sizeof(sock);
 	if (getpeername(desc, (struct sockaddr *) &sock, &size) < 0)
 	{
-		perror("New_descriptor: getpeername");
+		log_error("New_descriptor: getpeername");
 		dnew->host = str_dup("(unknown)");
 	}
 	else
@@ -794,18 +714,19 @@
 		/*
 		 * Would be nice to use inet_ntoa here but it takes a struct arg,
 		 * which ain't very compatible between gcc and system libraries.
+		 * - who cares lets use it, Markanth 03/07/2003
 		 */
-		int addr;
+		char *ip = inet_ntoa(sock.sin_addr);
+		logf("Sock.sinaddr:  %s", ip);
 
-		addr = ntohl(sock.sin_addr.s_addr);
-		sprintf(buf, "%d.%d.%d.%d", (addr >> 24) & 0xFF,
-				(addr >> 16) & 0xFF, (addr >> 8) & 0xFF, (addr) & 0xFF);
-		sprintf(log_buf, "Sock.sinaddr:  %s", buf);
-		log_string(log_buf);
-		from =
-			gethostbyaddr((char *) &sock.sin_addr,
-						  sizeof(sock.sin_addr), AF_INET);
-		dnew->host = str_dup(from ? from->h_name : buf);
+		if (!IS_SET(mud_info.mud_flags, NO_DNS_LOOKUPS))
+			from =
+				gethostbyaddr((char *) &sock.sin_addr,
+							  sizeof(sock.sin_addr), AF_INET);
+		else
+			from = NULL;
+
+		dnew->host = str_dup(from ? from->h_name : ip);
 	}
 
 	/*
@@ -818,8 +739,7 @@
 	 */
 	if (check_ban(dnew->host, BAN_ALL))
 	{
-		write_to_descriptor(dnew,
-							"Your site has been banned from this mud.\n\r", 0);
+		d_write(dnew, "Your site has been banned from this mud.\n\r", 0);
 		close(desc);
 		free_descriptor(dnew);
 		return;
@@ -833,8 +753,10 @@
 	 * Send the greeting.
 	 */
 	init_telnet(dnew);
-	write_to_buffer(dnew,
-					"Would you like ANSI color? (Y)es, (N)o, (T)est:\n\r", 0);
+	d_println(dnew, "Autodetecting IMP...v1.30", 0);
+	d_println(dnew, "This world is Pueblo 1.10 enhanced.", 0);
+	d_println(dnew,
+			  "Welcome, would you like ANSI color? (Y)es, (N)o, (T)est:", 0);
 	return;
 }
 
@@ -847,8 +769,7 @@
 
 	if (dclose->snoop_by != NULL)
 	{
-		write_to_buffer(dclose->snoop_by,
-						"Your victim has left the game.\n\r", 0);
+		d_println(dclose->snoop_by, "Your victim has left the game.", 0);
 	}
 
 	{
@@ -867,9 +788,9 @@
 		log_string(log_buf);
 		/* cut down on wiznet spam when rebooting */
 		/* If ch is writing note or playing, just lose link otherwise clear char */
-		if ((dclose->connected == CON_PLAYING && !merc_down) ||
-			((dclose->connected >= CON_NOTE_TO) &&
-			 (dclose->connected <= CON_NOTE_FINISH)))
+		if ((dclose->connected == CON_PLAYING && run_level != RUNLEVEL_SHUTDOWN)
+			|| ((dclose->connected >= CON_NOTE_TO)
+				&& (dclose->connected <= CON_NOTE_FINISH)))
 		{
 			act("$n has lost $s link.", ch, NULL, NULL, TO_ROOM);
 			wiznet("Net death has claimed $N.", ch, NULL, WIZ_LINKS, 0, 0);
@@ -905,12 +826,12 @@
 bool read_from_descriptor(DESCRIPTOR_DATA * d)
 {
 	unsigned int iStart, index;
-	static char buf[sizeof(d->inbuf)];
+	static unsigned char buf[sizeof(d->inbuf)];
 
 	memset(buf, 0, sizeof(buf));
 
 	/* Hold horses if pending command already. */
-	if (d->incomm[0] != '\0')
+	if (!IS_NULLSTR(d->incomm))
 		return TRUE;
 
 	/* Check for overflow. */
@@ -920,7 +841,7 @@
 	if (iStart >= sizeof(d->inbuf) - 10)
 	{
 		logf("%s input overflow!", d->host);
-		write_to_descriptor(d, "\n\r*** PUT A LID ON IT!!! ***\n\r", 0);
+		d_write(d, "\n\r*** PUT A LID ON IT!!! ***\n\r", 0);
 		d->inbuf[sizeof(d->inbuf) - 10] = '\0';
 		return TRUE;
 	}
@@ -945,7 +866,7 @@
 			break;
 		else
 		{
-			perror("Read_from_descriptor");
+			log_error("Read_from_descriptor");
 			return FALSE;
 		}
 	}
@@ -953,16 +874,19 @@
 	/* process_telnet does the actual writing in d->inbuf now! */
 	process_telnet(d, index, buf);
 
-	if (d->connected == CON_GET_TERM && (DESC_FLAGGED(d, DESC_TELOPT_EOR) ||
-										 DESC_FLAGGED(d, DESC_TELOPT_ECHO)
-										 || DESC_FLAGGED(d, DESC_TELOPT_NAWS)
+	/* If there is some telnet negotation going on, assume the client
+	   supports colour... */
+	if (d->connected == CON_GET_TERM &&
+		(DESC_FLAGGED(d, DESC_TELOPT_EOR | DESC_TELOPT_ECHO | DESC_TELOPT_NAWS
+					  | DESC_MXP | DESC_MSP | DESC_PUEBLO | DESC_TELOPT_TTYPE |
+					  DESC_TELOPT_BINARY | DESC_PORTAL | DESC_IMP)
 #if !defined(NO_MCCP)
-										 || d->out_compress
+		 || d->out_compress
 #endif
 		))
 	{
 		SET_BIT(d->d_flags, DESC_COLOUR);
-		write_to_buffer(d, "{`Colour{c enabled Automatically...{x\n\r", 0);
+		d_println(d, "{`Colour{x enabled Automatically...{x", 0);
 		show_greeting(d);
 		d->connected = CON_GET_NAME;
 	}
@@ -979,7 +903,7 @@
 	/*
 	 * Hold horses if pending command already.
 	 */
-	if (d->incomm[0] != '\0')
+	if (!IS_NULLSTR(d->incomm))
 		return;
 
 	if (d->character && d->character->position == POS_FIGHTING && d->run_buf)
@@ -1074,7 +998,7 @@
 	{
 		if (k >= MAX_INPUT_LENGTH - 2)
 		{
-			write_to_descriptor(d, "Line too long.\n\r", 0);
+			d_write(d, "Line too long.\n\r", 0);
 
 			/* skip the rest of the line */
 			for (; d->inbuf[i] != '\0'; i++)
@@ -1129,7 +1053,7 @@
 
 				d->repeat = 0;
 /*
-		write_to_descriptor( d,
+		d_write( d,
 		    "\n\r*** PUT A LID ON IT!!! ***\n\r", 0 );
 		strcpy( d->incomm, "quit" );
 */
@@ -1200,12 +1124,12 @@
 }
 
 /* Taken from Gary McNickel's WOTmud 
-   Updated by Markanth */
+   Updated by Markanth. */
 bool process_ansi_output(DESCRIPTOR_DATA * d)
 {
 	CHAR_DATA *ch;
 	char *counter;
-	char output[MSL * 10];
+	char output[MSL];
 	char temp[MSL];
 	char *work;
 	bool success = TRUE;
@@ -1227,7 +1151,7 @@
 
 			*counter++ = '\0';
 
-			if (!(success = write_to_descriptor(d, output, strlen(output))))
+			if (!(success = d_write(d, output, strlen(output))))
 				break;
 
 			memset(output, 0, sizeof(output));
@@ -1411,7 +1335,7 @@
 
 			if (slot < 0 || slot >= MAX_CUSTOM_COLOUR)
 			{
-				bug("ansi_output: invalid custom color", 0);
+				bug("ansi_output: invalid custom color");
 				strcpy(temp, CL_DEFAULT);
 				col_attr = CL_CLEAR;
 				col_fore = FG_NONE;
@@ -1431,7 +1355,7 @@
 			*counter++ = *work++;
 	}
 
-	success = success && (write_to_descriptor(d, output, strlen(output)));
+	success = success && (d_write(d, output, strlen(output)));
 
 	d->outtop = 0;
 	return success;
@@ -1446,11 +1370,10 @@
 	/*
 	 * Bust a prompt.
 	 */
-	if (!merc_down)
+	if (run_level != RUNLEVEL_SHUTDOWN)
 	{
 		if (d->showstr_point)
 		{
-			char buf[MSL];
 			const char *ptr;
 			int shown_lines = 0;
 			int total_lines = 0;
@@ -1464,16 +1387,14 @@
 				if (*ptr == '\n')
 					total_lines++;
 
-			sprintf(buf,
-					"\n\r(%d%%) Please type (H)elp, (R)efresh, (B)ack, or (C)ontinue or hit ENTER.\n\r",
-					100 * shown_lines / total_lines);
-			write_to_buffer(d, buf, 0);
-
+			d_printlnf(d,
+					   "\n\r(%d%%) Please type (H)elp, (R)efresh, (B)ack, or (C)ontinue or hit ENTER.",
+					   100 * shown_lines / total_lines);
 		}
 		else if (fPrompt && d->pString && d->connected == CON_PLAYING)
-			write_to_buffer(d, "> ", 2);
+			d_print(d, "> ", 2);
 		else if (fPrompt && d->connected == CON_NOTE_TEXT)
-			write_to_buffer(d, "> ", 2);
+			d_print(d, "> ", 2);
 		else if (fPrompt && d->connected == CON_PLAYING)
 		{
 			CHAR_DATA *ch;
@@ -1486,7 +1407,6 @@
 			{
 				int percent;
 				char wound[100];
-				char buf[MAX_STRING_LENGTH];
 
 				if (victim->max_hit > 0)
 					percent = victim->hit * 100 / victim->max_hit;
@@ -1510,37 +1430,36 @@
 				else
 					sprintf(wound, "is bleeding to death.");
 
-				sprintf(buf, "%s %s \n\r",
-						IS_NPC(victim) ? victim->short_descr :
-						victim->name, wound);
-				buf[0] = UPPER(buf[0]);
-				write_to_buffer(d, buf, 0);
+				d_printlnf(d, "%s %s",
+						   IS_NPC(victim) ? victim->short_descr :
+						   victim->name, wound);
 			}
 
 			ch = d->original ? d->original : d->character;
 			if (!IS_SET(ch->comm, COMM_COMPACT)
-				&& (d->fcommand || ch->fighting || d->editor > 0))
-				write_to_buffer(d, "\n\r", 2);
+				&& ((!IS_NPC(ch) && IS_SET(ch->act, PLR_AUTOPROMPT))
+					|| d->fcommand || ch->fighting || d->editor != ED_NONE))
+				d_println(d, "", 0);
 
 			if (IS_SET(ch->comm, COMM_PROMPT))
 			{
-				if ((d->fcommand && !d->run_buf) || ch->fighting)
+				if ((!IS_NPC(ch) && IS_SET(ch->act, PLR_AUTOPROMPT))
+					|| (d->fcommand && !d->run_buf) || ch->fighting)
 					bust_a_prompt(d->character);
-				else if (d->editor > 0)
+				else if (d->editor != ED_NONE)
 				{
 					chprintlnf(ch, "{cOLC %s : {W%s{x",
-							   olc_ed_name(d->character),
-							   olc_ed_vnum(d->character));
+							   olc_ed_name(d), olc_ed_vnum(d));
 				}
 			}
 			if (IS_SET(ch->comm, COMM_TELNET_GA))
 			{
-				write_to_buffer(d, go_ahead_str, 0);
+				d_write(d, go_ahead_str, 0);
 			}
 			else if (IS_SET(ch->comm, COMM_TELNET_EOR))
 			{
 				char eor_str[] = { IAC, EOR, '\0' };
-				write_to_buffer(d, eor_str, 0);
+				d_write(d, eor_str, 0);
 			}
 		}
 
@@ -1558,9 +1477,9 @@
 	if (d->snoop_by != NULL)
 	{
 		if (d->character != NULL)
-			write_to_buffer(d->snoop_by, d->character->name, 0);
-		write_to_buffer(d->snoop_by, "> ", 2);
-		write_to_buffer(d->snoop_by, d->outbuf, d->outtop);
+			d_print(d->snoop_by, d->character->name, 0);
+		d_print(d->snoop_by, "> ", 2);
+		d_print(d->snoop_by, d->outbuf, d->outtop);
 	}
 
 	/*
@@ -1588,7 +1507,10 @@
 
 	point = buf;
 	str = ch->prompt;
-	if (str == NULL || str[0] == '\0')
+
+	bust_a_portal(ch);
+
+	if (IS_NULLSTR(str))
 	{
 		chprintlnf(ch, "<%ldhp %ldm %ldmv> %s", ch->hit, ch->mana,
 				   ch->move, ch->prefix);
@@ -1601,6 +1523,8 @@
 		return;
 	}
 
+	chprint(ch, MXPTAG("Prompt"));
+
 	while (*str != '\0')
 	{
 		if (*str != '%')
@@ -1627,12 +1551,14 @@
 					!IS_SET(pexit->exit_info, EX_CLOSED))
 				{
 					found = TRUE;
+					strcat(doors, MXPTAG("Ex"));
 					strcat(doors, dir_letter[door]);
+					strcat(doors, MXPTAG("/Ex"));
 				}
 			}
 			if (!found)
 				strcat(buf, "none");
-			sprintf(buf2, "%s", doors);
+			sprintf(buf2, MXPTAG("Rexits") "%s" MXPTAG("/Rexits"), doors);
 			i = buf2;
 			break;
 		case 'c':
@@ -1640,27 +1566,29 @@
 			i = buf2;
 			break;
 		case 'h':
-			sprintf(buf2, "%ld", ch->hit);
+			sprintf(buf2, MXPTAG("Hp") "%ld" MXPTAG("/Hp"), ch->hit);
 			i = buf2;
 			break;
 		case 'H':
-			sprintf(buf2, "%ld", ch->max_hit);
+			sprintf(buf2, MXPTAG("MaxHp") "%ld" MXPTAG("/MaxHp"), ch->max_hit);
 			i = buf2;
 			break;
 		case 'm':
-			sprintf(buf2, "%ld", ch->mana);
+			sprintf(buf2, MXPTAG("Mana") "%ld" MXPTAG("/Mana"), ch->mana);
 			i = buf2;
 			break;
 		case 'M':
-			sprintf(buf2, "%ld", ch->max_mana);
+			sprintf(buf2, MXPTAG("MaxMana") "%ld" MXPTAG("/MaxMana"),
+					ch->max_mana);
 			i = buf2;
 			break;
 		case 'v':
-			sprintf(buf2, "%ld", ch->move);
+			sprintf(buf2, MXPTAG("Move") "%ld" MXPTAG("/Move"), ch->move);
 			i = buf2;
 			break;
 		case 'V':
-			sprintf(buf2, "%ld", ch->max_move);
+			sprintf(buf2, MXPTAG("MaxMove") "%ld" MXPTAG("/MaxMove"),
+					ch->max_move);
 			i = buf2;
 			break;
 		case 'x':
@@ -1698,8 +1626,8 @@
 						((!IS_NPC(ch) &&
 						  IS_SET(ch->act, PLR_HOLYLIGHT)) ||
 						 (!IS_AFFECTED(ch, AFF_BLIND) &&
-						  !room_is_dark(ch->in_room))) ? ch->in_room->
-						name : "darkness");
+						  !room_is_dark(ch->in_room))) ? ch->
+						in_room->name : "darkness");
 			else
 				sprintf(buf2, " ");
 			i = buf2;
@@ -1731,11 +1659,12 @@
 			i = buf2;
 			break;
 		case 'o':
-			sprintf(buf2, "%s", olc_ed_name(ch));
+			sprintf(buf2, MXPTAG("Olc") "%s" MXPTAG("/Olc"),
+					olc_ed_name(ch->desc));
 			i = buf2;
 			break;
 		case 'O':
-			sprintf(buf2, "%s", olc_ed_vnum(ch));
+			sprintf(buf2, "%s", olc_ed_vnum(ch->desc));
 			i = buf2;
 			break;
 		case 'q':
@@ -1756,23 +1685,42 @@
 		while ((*point = *i) != '\0')
 			++point, ++i;
 	}
-	write_to_buffer(ch->desc, buf, point - buf);
-
-	if (ch->prefix[0] != '\0')
-		write_to_buffer(ch->desc, ch->prefix, 0);
+	d_print(ch->desc, buf, point - buf);
+	d_print(ch->desc, MXPTAG("/Prompt"), 0);
+	if (!IS_NULLSTR(ch->prefix))
+		d_print(ch->desc, ch->prefix, 0);
 	return;
 }
 
 /*
  * Append onto an output buffer.
  */
-void write_to_buffer(DESCRIPTOR_DATA * d, const char *txt, int length)
+void d_print(DESCRIPTOR_DATA * d, const char *txt, int length)
 {
+	int origlength;
+	bool noMXP = FALSE;
+
+	if (!d)
+		return;
+
 	/*
 	 * Find length in case caller didn't.
 	 */
-	if (length <= 0)
+	if (length == 0)
 		length = strlen(txt);
+	else if (length <= -1)
+	{
+		/* if length is less than 0, disable MXP parsing,
+		   good for sending strings EXACTLY the way they appear */
+		noMXP = TRUE;
+		length = strlen(txt);
+	}
+
+	origlength = length;
+
+	/* work out how much we need to expand/contract it */
+	if (!noMXP)
+		length += count_mxp_tags(d, txt, length);
 
 	/*
 	 * Initial \n\r if needed.
@@ -1793,7 +1741,7 @@
 
 		if (d->outsize >= 32000)
 		{
-			bug("Buffer overflow. Closing.\n\r", 0);
+			bug("Buffer overflow. Closing.");
 			close_socket(d);
 			return;
 		}
@@ -1807,26 +1755,80 @@
 	/*
 	 * Copy.
 	 */
-	strncpy((char *) d->outbuf + d->outtop, txt, length);
+	strncpy(d->outbuf + d->outtop, txt, length);
+	if (!noMXP)
+		convert_mxp_tags(d, d->outbuf + d->outtop, txt, origlength);
 	d->outtop += length;
+	d->outbuf[d->outtop] = NUL;
 	return;
 }
 
+void d_println(DESCRIPTOR_DATA * d, const char *txt, int length)
+{
+	if (!d)
+		return;
+
+	if (!IS_NULLSTR(txt))
+		d_print(d, txt, length);
+	d_print(d, "\n\r", 2);
+}
+
+void d_printf(DESCRIPTOR_DATA * d, const char *txt, ...)
+{
+	int length;
+	va_list args;
+	char buf[MSL * 2];
+
+	if (!d || IS_NULLSTR(txt))
+		return;
+
+	va_start(args, txt);
+	length = vsnprintf(buf, sizeof(buf), txt, args);
+	va_end(args);
+
+	d_print(d, buf, length);
+}
+
+void d_printlnf(DESCRIPTOR_DATA * d, const char *txt, ...)
+{
+	if (!d)
+		return;
+
+	if (!IS_NULLSTR(txt))
+	{
+		int length;
+		va_list args;
+		char buf[MSL * 2];
+
+		va_start(args, txt);
+		length = vsnprintf(buf, sizeof(buf), txt, args);
+		va_end(args);
+
+		d_print(d, buf, length);
+	}
+	d_print(d, "\n\r", 2);
+}
+
 /*
  * Lowest level output function.
  * Write a block of text to the file descriptor.
  * If this gives errors on very long blocks (like 'ofind all'),
  *   try lowering the max block size.
  */
-bool write_to_descriptor(DESCRIPTOR_DATA * d, char *txt, int length)
+bool d_write(DESCRIPTOR_DATA * d, const char *txt, int length)
 {
 	int iStart;
 	int nWrite;
 	int nBlock;
 
+	if (!d)
+		return FALSE;
+
 	if (length <= 0)
 		length = strlen(txt);
 
+	d->bytes_normal += length;
+
 #if !defined(NO_MCCP)
 	if (d->out_compress)
 		return writeCompressed(d, txt, length);
@@ -1838,7 +1840,7 @@
 			nBlock = UMIN(length - iStart, 4096);
 			if ((nWrite = write(d->descriptor, txt + iStart, nBlock)) < 0)
 			{
-				perror("Write_to_descriptor");
+				log_error("d_write");
 				return FALSE;
 			}
 		}
@@ -1956,8 +1958,7 @@
 		{
 			if (fConn == FALSE)
 			{
-				free_string(d->character->pcdata->pwd);
-				d->character->pcdata->pwd = str_dup(ch->pcdata->pwd);
+				replace_string(d->character->pcdata->pwd, ch->pcdata->pwd);
 			}
 			else
 			{
@@ -1965,7 +1966,8 @@
 				d->character = ch;
 				ch->desc = d;
 				ch->timer = 0;
-				chprintln(ch, "Reconnecting. Type replay to see missed tells.");
+				chprintln(ch,
+						  "Reconnecting. Welcome back, type replay to see missed tells.");
 				act("$n has reconnected.", ch, NULL, NULL, TO_ROOM);
 
 				sprintf(log_buf, "%s@%s reconnected.", ch->name, d->host);
@@ -2000,11 +2002,11 @@
 			dold->connected != CON_GET_NAME &&
 			dold->connected != CON_GET_OLD_PASSWORD &&
 			!str_cmp(name,
-					 dold->original ? dold->original->name : dold->character->
-					 name))
+					 dold->original ? dold->original->name : dold->
+					 character->name))
 		{
-			write_to_buffer(d, "That character is already playing.\n\r", 0);
-			write_to_buffer(d, "Do you wish to connect anyway (Y/N)?", 0);
+			d_println(d, "That character is already playing.", 0);
+			d_print(d, "Do you wish to connect anyway (Y/N)?", 0);
 			d->connected = CON_BREAK_CONNECT;
 			return TRUE;
 		}
@@ -2033,8 +2035,8 @@
  */
 void chprint(CHAR_DATA * ch, const char *txt)
 {
-	if (txt != NULL && ch && ch->desc != NULL)
-		write_to_buffer(ch->desc, txt, strlen(txt));
+	if (!IS_NULLSTR(txt) && ch && ch->desc != NULL)
+		d_print(ch->desc, txt, strlen(txt));
 	return;
 }
 
@@ -2042,9 +2044,9 @@
 {
 	if (ch && ch->desc != NULL)
 	{
-		if (txt != NULL)
-			write_to_buffer(ch->desc, txt, strlen(txt));
-		write_to_buffer(ch->desc, "\n\r", 2);
+		if (!IS_NULLSTR(txt))
+			d_print(ch->desc, txt, strlen(txt));
+		d_print(ch->desc, "\n\r", 2);
 	}
 
 	return;
@@ -2053,16 +2055,16 @@
 /*
  * Send a page to one char.
  */
-void page_to_char(const char *txt, CHAR_DATA * ch)
+void sendpage(CHAR_DATA * ch, const char *txt)
 {
 	DESCRIPTOR_DATA *d;
 
-	if (txt == NULL || (d = ch->desc) == NULL)
+	if (IS_NULLSTR(txt) || (d = ch->desc) == NULL)
 		return;
 
-	if (ch->lines == 0)
+	if (ch->lines <= 0)
 	{
-		write_to_buffer(d, txt, strlen(txt));
+		d_print(d, txt, strlen(txt));
 		return;
 	}
 
@@ -2103,6 +2105,7 @@
 	register char *scan2;
 	register const char *chk;
 	int lines = 0;
+	int maxlines = get_scr_lines(d->character);
 	int toggle = 1;
 
 	one_argument(input, buf);
@@ -2115,21 +2118,20 @@
 		break;
 
 	case 'R':					/* refresh current page of text */
-		lines = -1 - (d->character->lines);
+		lines = -1 - maxlines;
 		break;
 
 	case 'B':					/* scroll back a page of text */
-		lines = -(2 * (int) d->character->lines);
+		lines = -(2 * maxlines);
 		break;
 
 	case '?':
 	case 'H':					/* Show some help */
-		write_to_buffer(d, "Pager help:\n\r" "C or Enter     next page\n\r"
-						"R              refresh this page\n\r", 0);
-		write_to_buffer(d,
-						"B              previous page\n\r"
-						"H or ?         help\n\r" "Any other keys exit.\n\r",
-						0);
+		d_println(d, "Pager help:\n\r" "C or Enter     next page\n\r"
+				  "R              refresh this page", 0);
+		d_println(d,
+				  "B              previous page\n\r"
+				  "H or ?         help\n\r" "Any other keys exit.", 0);
 		return;
 
 	default:					/*otherwise, stop the text viewing */
@@ -2165,11 +2167,11 @@
 			lines++;
 		else if (!*scan2
 				 || (d->character && !IS_NPC(d->character)
-					 && lines >= (int) d->character->lines))
+					 && lines >= maxlines))
 		{
 
 			*scan2 = '\0';
-			write_to_buffer(d, buffer, strlen(buffer));
+			d_print(d, buffer, strlen(buffer));
 
 			/* See if this is the end (or near the end) of the string */
 			for (chk = d->showstr_point; isspace(*chk); chk++);
@@ -2391,7 +2393,7 @@
 	if (to->desc)
 	{
 		if (to->desc->connected == CON_PLAYING)
-			write_to_buffer(to->desc, buf, point - buf);
+			d_print(to->desc, buf, point - buf);
 	}
 	else if (IS_NPC(to) && MOBtrigger && HAS_TRIGGER_MOB(to, TRIG_ACT))
 		p_act_trigger(buf, to, NULL, NULL, ch, arg1, arg2, TRIG_ACT);
@@ -2632,7 +2634,7 @@
             && ((ch)->position >= min_pos))
 
 void act_new(const char *format, CHAR_DATA * ch, const void *arg1,
-			 const void *arg2, flag_t type, int min_pos)
+			 const void *arg2, flag_t type, position_t min_pos)
 {
 	DESCRIPTOR_DATA *d;
 	ROOM_INDEX_DATA *room;
@@ -2695,254 +2697,72 @@
 	return;
 }
 
-/* source: EOD, by John Booth <???> */
-
-void chprintf(CHAR_DATA * ch, char *fmt, ...)
+void chprintf(CHAR_DATA * ch, const char *fmt, ...)
 {
-	char buf[MAX_STRING_LENGTH];
+	char buf[MAX_STRING_LENGTH * 2];
 	va_list args;
+	int length;
+
+	if (IS_NULLSTR(fmt) || !ch->desc)
+		return;
+
 	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
+	length = vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
-	chprint(ch, buf);
+	d_print(ch->desc, buf, length);
 }
 
-void chprintlnf(CHAR_DATA * ch, char *fmt, ...)
+void chprintlnf(CHAR_DATA * ch, const char *fmt, ...)
 {
-	char buf[MAX_STRING_LENGTH];
-	va_list args;
-	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
-	va_end(args);
+	if (!ch || !ch->desc)
+		return;
+
+	if (!IS_NULLSTR(fmt))
+	{
+		char buf[MAX_STRING_LENGTH * 2];
+		va_list args;
+		int length;
 
-	chprintln(ch, buf);
+		va_start(args, fmt);
+		length = vsnprintf(buf, sizeof(buf), fmt, args);
+		va_end(args);
+
+		d_print(ch->desc, buf, length);
+	}
+	d_print(ch->desc, "\n\r", 2);
 }
-void bugf(char *fmt, ...)
+
+void bugf(const char *fmt, ...)
 {
 	char buf[2 * MSL];
 	va_list args;
+
+	if (IS_NULLSTR(fmt))
+		return;
+
 	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
-	bug(buf, 0);
+	bug(buf);
 }
 
-void logf(char *fmt, ...)
+void logf(const char *fmt, ...)
 {
 	char buf[2 * MSL];
 	va_list args;
+
+	if (IS_NULLSTR(fmt))
+		return;
+
 	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
 	log_string(buf);
 }
 
-void update_last_func(DESCRIPTOR_DATA * d, const char *lstr, const char *sstr)
-{
-#if !defined(WIN32)
-	last_descriptor = d;
-	if (lstr != NULL)
-		strcpy(last_func_long, lstr);
-	if (sstr != NULL)
-		strcpy(last_func_short, sstr);
-#endif
-}
-
-#if !defined(WIN32)
-
-#if !defined(__CYGWIN__)
-
-#define	CORE_EXAMINE_SCRIPT	"../corefiles/gdbscript"
-
-#endif
-
-void halt_mud(int sig)
-{
-	DESCRIPTOR_DATA *d;
-	CHAR_DATA *ch;
-	char message[MSL];
-#if !defined(__CYGWIN__)
-	struct sigaction default_action;
-	pid_t forkpid;
-	int i;
-	int status;
-
-	waitpid(-1, &status, WNOHANG);
-	if (!crashed)
-	{
-#endif
-		crashed++;
-		logf("GAME CRASHED (SIGNAL %d, %s).", sig, strsignal(sig));
-		logf("Last recored function: %s", last_func_long);
-		// Inform last command typer that he caused the crash
-		if (last_descriptor && !IS_NULLSTR(last_func_short))
-		{
-			write_to_descriptor(last_descriptor,
-								"\n\rThe last command you typed, '", 0);
-			write_to_descriptor(last_descriptor, last_func_short, 0);
-			write_to_descriptor(last_descriptor,
-								"', might have caused this crash.\n\r"
-								"Please note any unusual circumstances to IMP and avoid using that command.\n\r",
-								0);
-		}
-		sprintf(message,
-				"\n\r---CRASH INFORMATION---\n\rSignal %d (%s)\n\rLast recorded function: %s\n\rDetails: %s\n\n",
-				sig, strsignal(sig),
-				!IS_NULLSTR(last_func_short) ? last_func_short : "<unknown>",
-				last_func_long);
-
-		for (d = descriptor_first; d != NULL; d = d_next)
-		{
-			d_next = d->next;
-			ch = CH(d);
-			if (!ch)
-			{
-				close_socket(d);
-				continue;
-			}
-			if (IS_NPC(ch))
-				continue;
-
-			if ((sig == SIGVTALRM || sig == SIGALRM) && IS_IMMORTAL(ch))
-				write_to_descriptor(d,
-									"\n\rThe mud has been unresponsive for 2 minutes.  Rebooting.\n\r",
-									0);
-
-			write_to_descriptor(d, "\n\rThe mud has CRASHED.\007\n\r", 0);
-
-			if (IS_IMMORTAL(ch))
-				write_to_descriptor(d, message, 0);
-		}
-
-		// try to save all characters - save_char_obj has sanity checking
-		for (d = descriptor_first; d != NULL; d = d_next)
-		{
-			d_next = d->next;
-			ch = CH(d);
-			if (!ch)
-			{
-				close_socket(d);
-				continue;
-			}
-			save_char_obj(ch);
-		}
-
-#if defined(__CYGWIN__)
-		set_shutdown(TRUE);
-		exit(0);
-#else
-		// success - proceed with fork/copyover plan.  Otherwise will go to
-		// next section and crash with a full reboot to recover
-		if ((forkpid = fork()) > 0)
-		{
-			// Parent process copyover and exit 
-			waitpid(forkpid, &status, WNOHANG);
-			// this requires you to add an "if (ch)" before the chprint
-			// statements in do_copyover.
-			do_copyover(NULL, "");
-			exit(0);
-		}
-		else if (forkpid < 0)
-		{
-			exit(1);
-		}
-		// Child process proceed to dump
-		// Close all files!
-		for (i = 255; i >= 0; i--)
-			close(i);
-
-		// Dup /dev/null to STD{IN,OUT,ERR}
-		open("/dev/null", O_RDWR);
-		dup(0);
-		dup(0);
-
-		default_action.sa_handler = SIG_DFL;
-		sigaction(sig, &default_action, NULL);
-
-		// Run gdb script.
-		if (!fork())
-		{
-			execl(CORE_EXAMINE_SCRIPT, CORE_EXAMINE_SCRIPT, (char *) NULL);
-			exit(0);
-		}
-		else
-			return;
-		raise(sig);
-	}
-
-	if (crashed == 1)
-	{
-		crashed++;
-
-		for (d = descriptor_first; d != NULL; d = d_next)
-		{
-			d_next = d->next;
-			ch = d->original ? d->original : d->character;
-			if (ch == NULL)
-			{
-				close_socket(d);
-				continue;
-			}
-			if (IS_NPC(ch))
-				continue;
-			write_to_descriptor(d,
-								"** Error saving character files; conducting full reboot. **\007\n\r",
-								0);
-			close_socket(d);
-			continue;
-		}
-		log_string("CHARACTERS NOT SAVED.");
-		default_action.sa_handler = SIG_DFL;
-		sigaction(sig, &default_action, NULL);
-
-		if (!fork())
-		{
-			kill(getppid(), sig);
-			exit(1);
-		}
-		else
-			return;
-		raise(sig);
-	}
-
-	if (crashed == 2)
-	{
-		crashed++;
-		log_string("TOTAL GAME CRASH.");
-		default_action.sa_handler = SIG_DFL;
-		sigaction(sig, &default_action, NULL);
-
-		if (!fork())
-		{
-			kill(getppid(), sig);
-			exit(1);
-		}
-		else
-			return;
-		raise(sig);
-	}
-
-	if (crashed == 3)
-	{
-		default_action.sa_handler = SIG_DFL;
-		sigaction(sig, &default_action, NULL);
-
-		if (!fork())
-		{
-			kill(getppid(), sig);
-			exit(1);
-		}
-		else
-			return;
-		raise(sig);
-	}
-#endif
-}
-#endif
-
 void set_game_levels(int Old, int New)
 {
 	CMD_DATA *cmd;
@@ -2965,7 +2785,7 @@
 		if (cmd->level >= imm_level)
 			cmd->level += mod;
 	}
-	save_commands();
+	rw_commands(action_write);
 	for (pHelp = help_first; pHelp; pHelp = pHelp->next)
 	{
 		if (pHelp->level >= imm_level)
@@ -2997,7 +2817,7 @@
 		if (ban->level >= imm_level)
 			ban->level += mod;
 	}
-	save_bans();
+	rw_bans(action_write);
 	for (d = disabled_first; d; d = d->next)
 	{
 		if (d->level >= imm_level)
@@ -3012,41 +2832,105 @@
 				skill_table[sn].skill_level[x] += mod;
 		}
 	}
-	save_skills();
+	rw_skills(action_write);
 	for (mbr = mbr_first; mbr; mbr = mbr->next)
 	{
 		if (mbr->level >= imm_level)
 			mbr->level += mod;
 	}
-	save_members();
+	rw_members(action_write);
 }
 
-CH_CMD(do_crash)
+/* wrap text to screen length.  Ignore's new lines. 
+   Good for presenting long strings of text. */
+#if defined(__cplusplus)
+// a c++ example
+void DESCRIPTOR_DATA::wrap(const char *buf)
 {
-#if defined(WIN32)
-	chprintln(ch, "Sorry this command isn't available under windows.");
+	DESCRIPTOR_DATA *d = this;
 #else
-	if (IS_NULLSTR(argument))
-	{
-		chprintln(ch, "Syntax: crash confirm - send a SIGSEGV to the mud.");
-		chprintln(ch, "      : crash loop    - start an infinite loop.");
+void dwrap(DESCRIPTOR_DATA * d, const char *buf)
+{
+#endif
+	static char buffer[MSL * 5];
+	static char out[MSL * 5];
+	int width;
+	unsigned int pos;
+	char *p;
+
+	if (!d)
 		return;
-	}
 
-	if (!str_cmp(argument, "loop"))
+	width = SCR_WIDTH(d);
+
+	sprintf(buffer, "%s", buf);
+	reformat_desc(buffer);
+
+	p = &buffer[0];
+	pos = 0;
+
+	out[0] = NUL;
+
+	do
 	{
-		for (;;);
-		return;
+		pos = get_line(p, width);
+		if (pos > 0)
+		{
+			strncat(out, p, pos);
+			p += pos;
+		}
+		else
+		{
+			strcat(out, p);
+			break;
+		}
+		strcat(out, "\n\r");
 	}
-	else if (!str_cmp(argument, "confirm"))
-	{
-		raise(SIGSEGV);
+	while (TRUE);
+
+	d_print(d, out, 0);
+}
+
+void dwrapln(DESCRIPTOR_DATA * d, const char *buf)
+{
+	if (!d)
 		return;
-	}
-	else
-	{
-		do_crash(ch, "");
+
+	dwrap(d, buf);
+	d_print(d, "\n\r", 2);
+}
+
+void dwrapf(DESCRIPTOR_DATA * d, const char *buf, ...)
+{
+	va_list args;
+	char format[MSL * 5];
+
+	if (!d || IS_NULLSTR(buf))
 		return;
+
+	va_start(args, buf);
+	vsnprintf(format, sizeof(format), buf, args);
+	va_end(args);
+
+	dwrap(d, format);
+}
+
+void dwraplnf(DESCRIPTOR_DATA * d, const char *buf, ...)
+{
+	if (!d)
+		return;
+
+	if (!IS_NULLSTR(buf))
+	{
+		va_list args;
+		char format[MSL * 5];
+
+		va_start(args, buf);
+		vsnprintf(format, sizeof(format), buf, args);
+		va_end(args);
+
+		dwrap(d, format);
 	}
-#endif
+	d_print(d, "\n\r", 2);
+	return;
 }
diff -ur -x config -x o -x rom src/const.c new/const.c
--- src/const.c	Tue May 27 02:46:35 2003
+++ new/const.c	Sun Aug 31 19:23:20 2003
@@ -22,13 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <time.h>
 #include "merc.h"
 #include "magic.h"
 #include "interp.h"
@@ -103,6 +99,8 @@
 	{"switches", WIZ_SWITCHES, L2},
 	{"secure", WIZ_SECURE, L1},
 	{"bugs", WIZ_BUGS, L3},
+	{"telnet", WIZ_TELNET, L2},
+	{"chansnoop", WIZ_CHANSNOOP, L4},
 	{NULL, 0, 0}
 };
 
diff -ur -x config -x o -x rom src/db.c new/db.c
--- src/db.c	Tue May 27 02:46:35 2003
+++ new/db.c	Sun Aug 31 19:23:20 2003
@@ -22,25 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#else
-#include <process.h>
-#include <sys/timeb.h>
-#include <winsock2.h>
-#endif
 #define	IN_DB_C
 #include "merc.h"
 #include "db.h"
@@ -50,115 +35,79 @@
 #include "lookup.h"
 #include "olc.h"
 #include "interp.h"
-#if defined(WIN32)
-#include "../win32/winstuff.h"
-#endif
+#include "gcn.h"
+#include "tablesave.h"
+#include "save.h"
 #undef IN_DB_C
 
-extern int _filbuf args((FILE *));
-
-#if !defined(OLD_RAND)
-#if !defined(linux) && !defined(WIN32) && !defined(__CYGWIN__)
-long random();
-#endif
-#endif
-
 /*
  * Locals.
  */
 MOB_INDEX_DATA *mob_index_hash[MAX_KEY_HASH];
 OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
 ROOM_INDEX_DATA *room_index_hash[MAX_KEY_HASH];
-#if (STRHASH==1)
-char *string_hash[MAX_KEY_HASH];
-#endif
 
-AREA_DATA *area_first;
-AREA_DATA *area_last;
 AREA_DATA *current_area;
 
-char *top_string;
 char str_empty[1];
 
-int top_affect;
-int top_area;
-int top_ed;
-int top_exit;
-int top_help;
-int top_mob_index;
-int top_obj_index;
-int top_reset;
-int top_room;
-int top_explored;
-int top_shop;
-vnum_t top_vnum_room;			/* OLC */
-vnum_t top_vnum_mob;			/* OLC */
-vnum_t top_vnum_obj;			/* OLC */
-int top_mprog_index;			/* OLC */
-int mobile_count = 0;
-const char *help_greeting;
-
 /*
  * Semi-locals.
  */
-FILE *fpArea;
+READ_DATA *fpArea;
 char strArea[MAX_INPUT_LENGTH];
 
 /*
  * Local booting procedures.
 */
-void init_mm args((void));
-void load_area args((FILE * fp));
-void new_load_area args((FILE * fp));	/* OLC */
-void load_helps args((FILE * fp));
-void load_old_mob args((FILE * fp));
-void load_old_obj args((FILE * fp));
-void load_resets args((FILE * fp));
-void load_rooms args((FILE * fp));
-void load_shops args((FILE * fp));
-void load_specials args((FILE * fp));
-void load_mobprogs args((FILE * fp));
-void load_objprogs args((FILE * fp));
-void load_roomprogs args((FILE * fp));
-void fix_objprogs args((void));
-void fix_roomprogs args((void));
-
-void fix_exits args((void));
-void fix_mobprogs args((void));
-
-/*
- * Big mama top level function.
- */
-void boot_db(void)
-{
-
-	/*
-	 * Init some data space stuff.
-	 */
-	{
-		log_string("Allocating String Space...");
-		strspace_alloc();
-		fBootDb = TRUE;
+PROTOTYPE(void init_mm, (void));
+PROTOTYPE(void load_area, (READ_DATA *));
+PROTOTYPE(void new_load_area, (READ_DATA *));	/* OLC */
+PROTOTYPE(void load_helps, (READ_DATA *));
+PROTOTYPE(void load_old_mob, (READ_DATA *));
+PROTOTYPE(void load_old_obj, (READ_DATA *));
+PROTOTYPE(void load_resets, (READ_DATA *));
+PROTOTYPE(void load_rooms, (READ_DATA *));
+PROTOTYPE(void load_shops, (READ_DATA *));
+PROTOTYPE(void load_specials, (READ_DATA *));
+PROTOTYPE(void load_mobprogs, (READ_DATA *));
+PROTOTYPE(void load_objprogs, (READ_DATA *));
+PROTOTYPE(void load_roomprogs, (READ_DATA *));
+PROTOTYPE(void fix_objprogs, (void));
+PROTOTYPE(void fix_roomprogs, (void));
+PROTOTYPE(void init_area_weather, (void));
+PROTOTYPE(void fix_exits, (void));
+PROTOTYPE(void fix_mobprogs, (void));
+PROTOTYPE(void init_www_history, (void));
+
+void load_time(void)
+{
+	long lhour, lday, lmonth;
+	int total;
+	bool fail = FALSE;
+	READ_DATA *time_file;
+
+	if ((time_file = open_read(TIME_FILE)) != NULL)
+	{
+
+		total =
+			sscanf(time_file->str, "%d %d %d %d", &(time_info.hour),
+				   &(time_info.day), &(time_info.month), &(time_info.year));
+		if (total != 4)
+		{
+			log_string("loading stored time failed, using default");
+			fail = TRUE;
+		}
+		close_read(time_file);
 	}
-
-	/*
-	 * Init random number generator.
-	 */
+	else
 	{
-		log_string("Starting random number generator...");
-		init_mm();
+		log_string("failed open of time_file, loading default time.");
+		fail = TRUE;
 	}
 
-	log_string("Loading classes...");
-	load_classes();
-
-	/*
-	 * Set time and weather.
-	 */
+	if (fail)
 	{
-		long lhour, lday, lmonth;
-		log_string("Setting time and weather...");
-
 		lhour = (current_time - 650336715) / (PULSE_TICK / PULSE_PER_SECOND);
 		time_info.hour = lhour % 24;
 		lday = lhour / 24;
@@ -166,40 +115,146 @@
 		lmonth = lday / 35;
 		time_info.month = lmonth % 17;
 		time_info.year = lmonth / 17;
+	}
+	if (time_info.hour < 5)
+	{
+		time_info.sunlight = SUN_DARK;
+	}
+	else if (time_info.hour < 6)
+	{
+		time_info.sunlight = SUN_RISE;
+	}
+	else if (time_info.hour < 19)
+	{
+		time_info.sunlight = SUN_LIGHT;
+	}
+	else if (time_info.hour < 20)
+	{
+		time_info.sunlight = SUN_SET;
+	}
+	else
+	{
+		time_info.sunlight = SUN_DARK;
+	}
 
-		if (time_info.hour < 5)
-			weather_info.sunlight = SUN_DARK;
-		else if (time_info.hour < 6)
-			weather_info.sunlight = SUN_RISE;
-		else if (time_info.hour < 19)
-			weather_info.sunlight = SUN_LIGHT;
-		else if (time_info.hour < 20)
-			weather_info.sunlight = SUN_SET;
-		else
-			weather_info.sunlight = SUN_DARK;
+	mud_info.weath_unit = 10;
+	mud_info.rand_factor = 2;
+	mud_info.climate_factor = 1;
+	mud_info.max_vector = mud_info.weath_unit * 3;
+}
 
-		weather_info.change = 0;
-		weather_info.mmhg = 960;
-		if (time_info.month >= 7 && time_info.month <= 12)
-			weather_info.mmhg += number_range(1, 50);
-		else
-			weather_info.mmhg += number_range(1, 80);
+void load_area_db(void)
+{
+	READ_DATA *fpList;
 
-		if (weather_info.mmhg <= 980)
-			weather_info.sky = SKY_LIGHTNING;
-		else if (weather_info.mmhg <= 1000)
-			weather_info.sky = SKY_RAINING;
-		else if (weather_info.mmhg <= 1020)
-			weather_info.sky = SKY_CLOUDY;
-		else
-			weather_info.sky = SKY_CLOUDLESS;
+	if ((fpList = open_read(AREA_LIST)) == NULL)
+	{
+		log_error(AREA_LIST);
+		exit(1);
+	}
+
+	for (;;)
+	{
+		strcpy(strArea, read_word(fpList));
+
+		if (strArea[0] == '$')
+			break;
+
+		if ((fpArea = open_read(AREA_DIR "%s", strArea)) == NULL)
+		{
+			log_error(strArea);
+			exit(1);
+		}
+
+		logf("Loading %s...", strArea);
+		current_area = NULL;
+
+		for (;;)
+		{
+			char *word;
 
+			if (read_letter(fpArea) != '#')
+			{
+				bug("Boot_db: # not found.");
+				exit(1);
+			}
+
+			word = read_word(fpArea);
+
+			if (word[0] == '$')
+				break;
+			else if (!str_cmp(word, "AREA"))
+				load_area(fpArea);
+			else if (!str_cmp(word, "AREADATA"))
+				new_load_area(fpArea);
+			else if (!str_cmp(word, "HELPS"))
+				load_helps(fpArea);
+			else if (!str_cmp(word, "MOBOLD"))
+				load_old_mob(fpArea);
+			else if (!str_cmp(word, "MOBILES"))
+				load_mobiles(fpArea);
+			else if (!str_cmp(word, "MOBPROGS"))
+				load_mobprogs(fpArea);
+			else if (!str_cmp(word, "OBJPROGS"))
+				load_objprogs(fpArea);
+			else if (!str_cmp(word, "ROOMPROGS"))
+				load_roomprogs(fpArea);
+			else if (!str_cmp(word, "OBJOLD"))
+				load_old_obj(fpArea);
+			else if (!str_cmp(word, "OBJECTS"))
+				load_objects(fpArea);
+			else if (!str_cmp(word, "RESETS"))
+				load_resets(fpArea);
+			else if (!str_cmp(word, "ROOMS"))
+				load_rooms(fpArea);
+			else if (!str_cmp(word, "SHOPS"))
+				load_shops(fpArea);
+			else if (!str_cmp(word, "SPECIALS"))
+				load_specials(fpArea);
+			else
+			{
+				bug("Boot_db: bad section name.");
+				exit(1);
+			}
+		}
+		close_read(fpArea);
 	}
+	close_read(fpList);
+	fpArea = NULL;
+}
+
+/*
+ * Big mama top level function.
+ */
+void boot_db(void)
+{
+
+	run_level = RUNLEVEL_BOOTING;
+
+	/*
+	 * Init random number generator.
+	 */
+	log_string("Starting random number generator...");
+	init_mm();
+
+	log_string("Loading mud data...");
+	rw_mud_data(action_read);
+
+	logf("Loading game time.");
+	load_time();
+
+	log_string("Loading classes...");
+	rw_classes(action_read);
 
 	log_string("Loading skills...");
-	load_skills();
+	rw_skills(action_read);
 	log_string("Loading groups...");
-	load_groups();
+	rw_groups(action_read);
+	log_string("Loading channels...");
+	rw_channels(action_read);
+#if !defined(NO_WEB)
+	init_www_history();
+#endif
 
 	/*
 	 * Assign gsn's for skills which have them.
@@ -214,104 +269,29 @@
 				&& skill_table[sn].pgsn != &gsn_null)
 				*skill_table[sn].pgsn = sn;
 		}
+		for (sn = 0; sn < maxChannel; sn++)
+		{
+			if (channel_table[sn].index != NULL
+				&& channel_table[sn].index != &gcn_null)
+				*channel_table[sn].index = sn;
+		}
 	}
 
+	crs_info.status = CRS_NONE;
+	crs_info.who = &str_empty[0];
+	crs_info.reason = &str_empty[0];
+	crs_info.timer = -1;
+
 	log_string("Loading races...");
-	load_races();
+	rw_races(action_read);
 	log_string("Loading clans...");
-	load_clans();
-	load_members();
+	rw_clans(action_read);
+	rw_members(action_read);
 
 	/*
 	 * Read in all the area files.
 	 */
-	{
-		FILE *fpList;
-
-		if ((fpList = file_open(AREA_LIST, "r")) == NULL)
-		{
-			perror(AREA_LIST);
-			exit(1);
-		}
-
-		for (;;)
-		{
-			strcpy(strArea, fread_word(fpList));
-			if (strArea[0] == '$')
-				break;
-
-			if (strArea[0] == '-')
-			{
-				fpArea = stdin;
-			}
-			else
-			{
-				if ((fpArea = file_open(strArea, "r")) == NULL)
-				{
-					perror(strArea);
-					exit(1);
-				}
-			}
-
-			logf("Loading %s...", strArea);
-			current_area = NULL;
-
-			for (;;)
-			{
-				char *word;
-
-				if (fread_letter(fpArea) != '#')
-				{
-					bug("Boot_db: # not found.", 0);
-					exit(1);
-				}
-
-				word = fread_word(fpArea);
-
-				if (word[0] == '$')
-					break;
-				else if (!str_cmp(word, "AREA"))
-					load_area(fpArea);
-				/* OLC */
-				else if (!str_cmp(word, "AREADATA"))
-					new_load_area(fpArea);
-				else if (!str_cmp(word, "HELPS"))
-					load_helps(fpArea);
-				else if (!str_cmp(word, "MOBOLD"))
-					load_old_mob(fpArea);
-				else if (!str_cmp(word, "MOBILES"))
-					load_mobiles(fpArea);
-				else if (!str_cmp(word, "MOBPROGS"))
-					load_mobprogs(fpArea);
-				else if (!str_cmp(word, "OBJPROGS"))
-					load_objprogs(fpArea);
-				else if (!str_cmp(word, "ROOMPROGS"))
-					load_roomprogs(fpArea);
-				else if (!str_cmp(word, "OBJOLD"))
-					load_old_obj(fpArea);
-				else if (!str_cmp(word, "OBJECTS"))
-					load_objects(fpArea);
-				else if (!str_cmp(word, "RESETS"))
-					load_resets(fpArea);
-				else if (!str_cmp(word, "ROOMS"))
-					load_rooms(fpArea);
-				else if (!str_cmp(word, "SHOPS"))
-					load_shops(fpArea);
-				else if (!str_cmp(word, "SPECIALS"))
-					load_specials(fpArea);
-				else
-				{
-					bug("Boot_db: bad section name.", 0);
-					exit(1);
-				}
-			}
-
-			if (fpArea != stdin)
-				file_close(fpArea);
-			fpArea = NULL;
-		}
-		file_close(fpList);
-	}
+	load_area_db();
 
 	/*
 	 * Fix up exits.
@@ -319,61 +299,57 @@
 	 * Reset all areas once.
 	 * Load up the songs, notes and ban files.
 	 */
-	{
-		fix_exits();
-		fix_mobprogs();
-		fix_objprogs();
-		fix_roomprogs();
-		fBootDb = FALSE;
-		convert_objects();		/* ROM OLC */
-		area_update();
-		log_string("Loading boards...");
-		load_boards();			/* Load all boards */
-		save_notes();
-		load_bans();
-		load_songs();
-		load_disabled();
-		log_string("Loading socials...");
-		load_social_table();
-		load_gquest_data();
-		load_war_data();
-		log_string("Loading commands...");
-		load_commands();
-		load_corpses();
-		load_donation_pit();
-		load_bank_data();
-		log_string("Loading deities...");
-		load_deities();
-		log_string("Loading web passwords...");
-		load_webpasses();
-		logf("Stored %d Areas, %d Rooms, %d Mobs & %d Objects", top_area,
-			 top_room, top_mob_index, top_obj_index);
-		log_string("Finished.");
-	}
+	fix_exits();
+	fix_mobprogs();
+	fix_objprogs();
+	fix_roomprogs();
+	run_level = RUNLEVEL_BOOT_NOEXIT;
+	convert_objects();			/* ROM OLC */
+	area_update();
+	log_string("Loading boards...");
+	load_boards();				/* Load all boards */
+	save_notes();
+	rw_bans(action_read);
+	rw_music(action_read);
+	load_disabled();
+	log_string("Loading socials...");
+	rw_socials(action_read);
+	rw_gquest_data(action_read);
+	rw_war_data(action_read);
+	log_string("Loading commands...");
+	rw_commands(action_read);
+	load_corpses();
+	load_donation_pit();
+	log_string("Loading deities...");
+	rw_deities(action_read);
+	log_string("Loading web passwords...");
+	rw_webpasswds(action_read);
+	logf("Initializing weather data.");
+	init_area_weather();
+	logf("Stored %d Areas, %d Rooms, %d Mobs & %d Objects", top_area,
+		 top_room, top_mob_index, top_obj_index);
+	log_string("Finished.");
 
 	return;
 }
 
-void convert_area_credits(AREA_DATA * pArea);
+PROTOTYPE(void convert_area_credits, (AREA_DATA *));
 
 /*
  * Snarf an 'area' header line.
  */
-void load_area(FILE * fp)
+void load_area(READ_DATA * fp)
 {
 	AREA_DATA *pArea;
 
 	pArea = new_area();
-	free_string(pArea->file_name);
-	pArea->file_name = fread_string(fp);
+	free_read_string(pArea->file_name, fp);
 
 	pArea->area_flags = AREA_LOADING;	/* OLC */
-	free_string(pArea->name);
-	pArea->name = fread_string(fp);
-	free_string(pArea->credits);
-	pArea->credits = fread_string(fp);
-	pArea->min_vnum = fread_number(fp);
-	pArea->max_vnum = fread_number(fp);
+	free_read_string(pArea->name, fp);
+	free_read_string(pArea->credits, fp);
+	pArea->min_vnum = read_number(fp);
+	pArea->max_vnum = read_number(fp);
 
 	add_area(pArea);
 	current_area = pArea;
@@ -383,33 +359,6 @@
 	return;
 }
 
-/*
- * OLC
- * Use these macros to load any new area formats that you choose to
- * support on your MUD.  See the new_load_area format below for
- * a short example.
- */
-#if defined(KEY)
-#undef KEY
-#endif
-
-#define KEY( literal, field, value )                \
-                if ( !str_cmp( word, literal ) )    \
-                {                                   \
-                    field  = value;                 \
-                    fMatch = TRUE;                  \
-                    break;                          \
-                                }
-
-#define SKEY( string, field )                       \
-                if ( !str_cmp( word, string ) )     \
-                {                                   \
-                    free_string( field );           \
-                    field = fread_string( fp );     \
-                    fMatch = TRUE;                  \
-                    break;                          \
-                                }
-
 /* OLC
  * Snarf an 'area' header line.   Check this format.  MUCH better.  Add fields
  * too.
@@ -420,45 +369,46 @@
  * Recall 3001
  * End
  */
-void new_load_area(FILE * fp)
+void new_load_area(READ_DATA * fp)
 {
 	AREA_DATA *pArea;
 	const char *word;
 	bool fMatch;
 
 	pArea = new_area();
-	free_string(pArea->file_name);
-	pArea->file_name = str_dup(strArea);
+	replace_string(pArea->file_name, strArea);
 
 	for (;;)
 	{
-		word = feof(fp) ? "End" : fread_word(fp);
+		word = steof(fp) ? "End" : read_word(fp);
 		fMatch = FALSE;
 
 		switch (UPPER(word[0]))
 		{
 		case 'L':
-			SKEY("LvlComment", pArea->lvl_comment);
+			KEYS("LvlComment", pArea->lvl_comment);
 			break;
 		case 'M':
-			KEY("MinLevel", pArea->min_level, fread_number(fp));
-			KEY("MaxLevel", pArea->max_level, fread_number(fp));
+			KEY("MinLevel", pArea->min_level, read_number(fp));
+			KEY("MaxLevel", pArea->max_level, read_number(fp));
 			break;
 		case 'N':
-			SKEY("Name", pArea->name);
+			KEYS("Name", pArea->name);
 			break;
 		case 'F':
-			KEY("Flags", pArea->area_flags, fread_flag(fp));
+			KEY("Flags", pArea->area_flags, read_flag(fp));
 			break;
 		case 'S':
-			KEY("Security", pArea->security, fread_number(fp));
+			KEY("Security", pArea->security, read_number(fp));
 			break;
 		case 'V':
-			KEY("Version", pArea->version, fread_number(fp));
+			KEY("Version", pArea->version, read_number(fp));
 			if (!str_cmp(word, "VNUMs"))
 			{
-				pArea->min_vnum = fread_number(fp);
-				pArea->max_vnum = fread_number(fp);
+				pArea->min_vnum = read_number(fp);
+				pArea->max_vnum = read_number(fp);
+				fMatch = TRUE;
+				break;
 			}
 			break;
 		case 'E':
@@ -474,10 +424,18 @@
 			}
 			break;
 		case 'B':
-			SKEY("Builders", pArea->builders);
+			KEYS("Builders", pArea->builders);
 			break;
 		case 'C':
-			SKEY("Credits", pArea->credits);
+			KEYS("Credits", pArea->credits);
+			if (!str_cmp(word, "Climate"))
+			{
+				pArea->weather.climate_temp = read_number(fp);
+				pArea->weather.climate_precip = read_number(fp);
+				pArea->weather.climate_wind = read_number(fp);
+				fMatch = TRUE;
+				break;
+			}
 			break;
 		}
 	}
@@ -503,7 +461,7 @@
 /*
  * Snarf a help section.
  */
-void load_helps(FILE * fp)
+void load_helps(READ_DATA * fp)
 {
 	HELP_DATA *pHelp;
 	int level;
@@ -511,8 +469,8 @@
 
 	for (;;)
 	{
-		level = fread_number(fp);
-		keyword = fread_string(fp);
+		level = read_number(fp);
+		keyword = read_string(fp);
 
 		if (keyword[0] == '$')
 			break;
@@ -521,8 +479,7 @@
 		pHelp->level = level;
 		free_string(pHelp->keyword);
 		pHelp->keyword = keyword;
-		free_string(pHelp->text);
-		pHelp->text = fread_string(fp);
+		free_read_string(pHelp->text, fp);
 
 		if (!str_cmp(pHelp->keyword, "greeting"))
 			help_greeting = pHelp->text;
@@ -538,7 +495,7 @@
 /*
  * Snarf a mob section.  old style 
  */
-void load_old_mob(FILE * fp)
+void load_old_mob(READ_DATA * fp)
 {
 	MOB_INDEX_DATA *pMobIndex;
 	/* for race updating */
@@ -547,7 +504,7 @@
 
 	if (!current_area)			/* OLC */
 	{
-		bug("Load_mobiles: no #AREA seen yet.", 0);
+		bug("Load_mobiles: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -557,75 +514,71 @@
 		char letter;
 		int iHash;
 
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		if (letter != '#')
 		{
-			bug("Load_mobiles: # not found.", 0);
+			bug("Load_mobiles: # not found.");
 			exit(1);
 		}
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (vnum == 0)
 			break;
 
-		fBootDb = FALSE;
+		run_level = RUNLEVEL_BOOT_NOEXIT;
 		if (get_mob_index(vnum) != NULL)
 		{
-			bug("Load_mobiles: vnum %d duplicated.", vnum);
+			bugf("Load_mobiles: vnum %ld duplicated.", vnum);
 			exit(1);
 		}
-		fBootDb = TRUE;
+		run_level = RUNLEVEL_BOOTING;
 
 		pMobIndex = new_mob_index();
 		pMobIndex->vnum = vnum;
 		pMobIndex->area = current_area;	/* OLC */
 		pMobIndex->new_format = FALSE;
-		free_string(pMobIndex->player_name);
-		pMobIndex->player_name = fread_string(fp);
-		free_string(pMobIndex->short_descr);
-		pMobIndex->short_descr = fread_string(fp);
-		free_string(pMobIndex->long_descr);
-		pMobIndex->long_descr = fread_string(fp);
-		free_string(pMobIndex->description);
-		pMobIndex->description = fread_string(fp);
+		free_read_string(pMobIndex->player_name, fp);
+		free_read_string(pMobIndex->short_descr, fp);
+		free_read_string(pMobIndex->long_descr, fp);
+		free_read_string(pMobIndex->description, fp);
 
 /*
 		pMobIndex->long_descr[0] = UPPER (pMobIndex->long_descr[0]);
 		pMobIndex->description[0] = UPPER (pMobIndex->description[0]);
 */
 
-		pMobIndex->act = fread_flag(fp) | ACT_IS_NPC;
-		pMobIndex->affected_by = fread_flag(fp);
+		pMobIndex->act = read_flag(fp) | ACT_IS_NPC;
+		pMobIndex->affected_by = read_flag(fp);
 		pMobIndex->pShop = NULL;
-		pMobIndex->alignment = fread_number(fp);
-		letter = fread_letter(fp);
-		pMobIndex->level = fread_number(fp);
+		pMobIndex->alignment = read_number(fp);
+		letter = read_letter(fp);
+		pMobIndex->level = read_number(fp);
 
 		/*
 		 * The unused stuff is for imps who want to use the old-style
 		 * stats-in-files method.
 		 */
-		fread_number(fp);		/* Unused */
-		fread_number(fp);		/* Unused */
-		fread_number(fp);		/* Unused */
-		/* 'd'      */ fread_letter(fp);
+		read_number(fp);		/* Unused */
+		read_number(fp);		/* Unused */
+		read_number(fp);		/* Unused */
+		/* 'd'      */ read_letter(fp);
 		/* Unused */
-		fread_number(fp);		/* Unused */
-		/* '+'      */ fread_letter(fp);
+		read_number(fp);		/* Unused */
+		/* '+'      */ read_letter(fp);
 		/* Unused */
-		fread_number(fp);		/* Unused */
-		fread_number(fp);		/* Unused */
-		/* 'd'      */ fread_letter(fp);
+		read_number(fp);		/* Unused */
+		read_number(fp);		/* Unused */
+		/* 'd'      */ read_letter(fp);
 		/* Unused */
-		fread_number(fp);		/* Unused */
-		/* '+'      */ fread_letter(fp);
+		read_number(fp);		/* Unused */
+		/* '+'      */ read_letter(fp);
 		/* Unused */
-		fread_number(fp);		/* Unused */
-		pMobIndex->wealth = fread_number(fp) / 20;
-		/* xp can't be used! */ fread_number(fp);
+		read_number(fp);		/* Unused */
+		pMobIndex->wealth = read_number(fp) / 20;
+		/* xp can't be used! */ read_number(fp);
 		/* Unused */
-		pMobIndex->start_pos = fread_number(fp);	/* Unused */
-		pMobIndex->default_pos = fread_number(fp);	/* Unused */
+		pMobIndex->start_pos = read_enum(position_t, fp);	/* Unused */
+		pMobIndex->default_pos = read_enum(position_t, fp);	/* Unused */
 
 		if (pMobIndex->start_pos < POS_SLEEPING)
 			pMobIndex->start_pos = POS_STANDING;
@@ -635,15 +588,15 @@
 		/*
 		 * Back to meaningful values.
 		 */
-		pMobIndex->sex = fread_number(fp);
+		pMobIndex->sex = read_number(fp);
 
 		/* compute the race BS */
 		one_argument(pMobIndex->player_name, name);
 
-		if (name[0] == '\0' || (race = race_lookup(name)) == NULL)
+		if (IS_NULLSTR(name) || (race = race_lookup(name)) == NULL)
 		{
 			/* fill in with blanks */
-			pMobIndex->race = race_lookup("human");
+			pMobIndex->race = default_race;
 			pMobIndex->off_flags =
 				OFF_DODGE | OFF_DISARM | OFF_TRIP | ASSIST_VNUM;
 			pMobIndex->imm_flags = 0;
@@ -669,7 +622,7 @@
 
 		if (letter != 'S')
 		{
-			bug("Load_mobiles: vnum %d non-S.", vnum);
+			bugf("Load_mobiles: vnum %ld non-S.", vnum);
 			exit(1);
 		}
 
@@ -689,13 +642,13 @@
 /*
  * Snarf an obj section.  old style 
  */
-void load_old_obj(FILE * fp)
+void load_old_obj(READ_DATA * fp)
 {
 	OBJ_INDEX_DATA *pObjIndex;
 
 	if (!current_area)			/* OLC */
 	{
-		bug("Load_objects: no #AREA seen yet.", 0);
+		bug("Load_objects: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -705,54 +658,51 @@
 		char letter;
 		int iHash;
 
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		if (letter != '#')
 		{
-			bug("Load_objects: # not found.", 0);
+			bug("Load_objects: # not found.");
 			exit(1);
 		}
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (vnum == 0)
 			break;
 
-		fBootDb = FALSE;
+		run_level = RUNLEVEL_BOOT_NOEXIT;
 		if (get_obj_index(vnum) != NULL)
 		{
-			bug("Load_objects: vnum %d duplicated.", vnum);
+			bugf("Load_objects: vnum %ld duplicated.", vnum);
 			exit(1);
 		}
-		fBootDb = TRUE;
+		run_level = RUNLEVEL_BOOTING;
 
 		pObjIndex = new_obj_index();
 		pObjIndex->vnum = vnum;
 		pObjIndex->area = current_area;	/* OLC */
 		pObjIndex->new_format = FALSE;
 		pObjIndex->reset_num = 0;
-		free_string(pObjIndex->name);
-		pObjIndex->name = fread_string(fp);
-		free_string(pObjIndex->short_descr);
-		pObjIndex->short_descr = fread_string(fp);
-		free_string(pObjIndex->description);
-		pObjIndex->description = fread_string(fp);
-		/* Action description */ fread_string(fp);
+		free_read_string(pObjIndex->name, fp);
+		free_read_string(pObjIndex->short_descr, fp);
+		free_read_string(pObjIndex->description, fp);
+		/* Action description */ read_string(fp);
 
 /*		pObjIndex->short_descr[0] = LOWER (pObjIndex->short_descr[0]);
 		pObjIndex->description[0] = UPPER (pObjIndex->description[0]); */
 
-		pObjIndex->item_type = fread_number(fp);
-		pObjIndex->extra_flags = fread_flag(fp);
-		pObjIndex->wear_flags = fread_flag(fp);
-		pObjIndex->value[0] = fread_number(fp);
-		pObjIndex->value[1] = fread_number(fp);
-		pObjIndex->value[2] = fread_number(fp);
-		pObjIndex->value[3] = fread_number(fp);
+		pObjIndex->item_type = read_number(fp);
+		pObjIndex->extra_flags = read_flag(fp);
+		pObjIndex->wear_flags = read_flag(fp);
+		pObjIndex->value[0] = read_number(fp);
+		pObjIndex->value[1] = read_number(fp);
+		pObjIndex->value[2] = read_number(fp);
+		pObjIndex->value[3] = read_number(fp);
 		pObjIndex->value[4] = 0;
 		pObjIndex->level = 0;
 		pObjIndex->condition = 100;
-		pObjIndex->weight = fread_number(fp);
-		pObjIndex->cost = fread_number(fp);	/* Unused */
-		/* Cost per day */ fread_number(fp);
+		pObjIndex->weight = read_number(fp);
+		pObjIndex->cost = read_number(fp);	/* Unused */
+		/* Cost per day */ read_number(fp);
 
 		if (pObjIndex->item_type == ITEM_WEAPON)
 		{
@@ -766,7 +716,7 @@
 		{
 			char pletter;
 
-			pletter = fread_letter(fp);
+			pletter = read_letter(fp);
 
 			if (pletter == 'A')
 			{
@@ -777,8 +727,8 @@
 				paf->type = -1;
 				paf->level = 20;	/* RT temp fix */
 				paf->duration = -1;
-				paf->location = fread_number(fp);
-				paf->modifier = fread_number(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->modifier = read_number(fp);
 				paf->bitvector = 0;
 				LINK(paf, pObjIndex->first_affect, pObjIndex->last_affect, next,
 					 prev);
@@ -790,10 +740,8 @@
 				EXTRA_DESCR_DATA *ed;
 
 				ed = new_extra_descr();
-				free_string(ed->keyword);
-				ed->keyword = fread_string(fp);
-				free_string(ed->description);
-				ed->description = fread_string(fp);
+				free_read_string(ed->keyword, fp);
+				free_read_string(ed->description, fp);
 				LINK(ed, pObjIndex->first_extra_descr,
 					 pObjIndex->last_extra_descr, next, prev);
 				top_ed++;
@@ -801,7 +749,7 @@
 
 			else
 			{
-				ungetc(pletter, fp);
+				fp->pos--;
 				break;
 			}
 		}
@@ -855,7 +803,7 @@
 /*
  * Snarf a reset section.
  */
-void load_resets(FILE * fp)
+void load_resets(READ_DATA * fp)
 {
 	RESET_DATA *pReset;
 	EXIT_DATA *pexit;
@@ -864,7 +812,7 @@
 
 	if (!current_area)
 	{
-		bug("Load_resets: no #AREA seen yet.", 0);
+		bug("Load_resets: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -872,23 +820,25 @@
 	{
 		char letter;
 
-		if ((letter = fread_letter(fp)) == 'S')
+		if ((letter = read_letter(fp)) == 'S')
 			break;
 
 		if (letter == '*')
 		{
-			fread_to_eol(fp);
+			read_to_eol(fp);
 			continue;
 		}
 
 		pReset = new_reset_data();
 		pReset->command = letter;
-		/* if_flag */ fread_number(fp);
-		pReset->arg1 = fread_number(fp);
-		pReset->arg2 = fread_number(fp);
-		pReset->arg3 = (letter == 'G' || letter == 'R') ? 0 : fread_number(fp);
-		pReset->arg4 = (letter == 'P' || letter == 'M') ? fread_number(fp) : 0;
-		fread_to_eol(fp);
+		/* if_flag */ read_number(fp);
+		pReset->arg1 = read_number(fp);
+		pReset->arg2 = read_number(fp);
+		pReset->arg3 = (letter == 'G'
+						|| (current_area->version < 3
+							&& letter == 'R')) ? 0 : read_number(fp);
+		pReset->arg4 = (letter == 'P' || letter == 'M') ? read_number(fp) : 0;
+		read_to_eol(fp);
 
 		switch (pReset->command)
 		{
@@ -917,7 +867,7 @@
 			switch (pReset->arg3)
 			{
 			default:
-				bug("Load_resets: 'D': bad 'locks': %d.", pReset->arg3);
+				bugf("Load_resets: 'D': bad 'locks': %ld.", pReset->arg3);
 				break;
 			case 0:
 				break;
@@ -955,13 +905,13 @@
 /*
  * Snarf a room section.
  */
-void load_rooms(FILE * fp)
+void load_rooms(READ_DATA * fp)
 {
 	ROOM_INDEX_DATA *pRoomIndex;
 
 	if (current_area == NULL)
 	{
-		bug("Load_resets: no #AREA seen yet.", 0);
+		bug("Load_resets: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -972,24 +922,24 @@
 		int door;
 		int iHash;
 
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		if (letter != '#')
 		{
-			bug("Load_rooms: # not found.", 0);
+			bug("Load_rooms: # not found.");
 			exit(1);
 		}
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (vnum == 0)
 			break;
 
-		fBootDb = FALSE;
+		run_level = RUNLEVEL_BOOT_NOEXIT;
 		if (get_room_index(vnum) != NULL)
 		{
-			bug("Load_rooms: vnum %d duplicated.", vnum);
+			bugf("Load_rooms: vnum %ld duplicated.", vnum);
 			exit(1);
 		}
-		fBootDb = TRUE;
+		run_level = RUNLEVEL_BOOTING;
 
 		pRoomIndex = new_room_index();
 		pRoomIndex->first_person = NULL;
@@ -998,16 +948,14 @@
 		pRoomIndex->first_extra_descr = NULL;
 		pRoomIndex->area = current_area;
 		pRoomIndex->vnum = vnum;
-		free_string(pRoomIndex->name);
-		pRoomIndex->name = fread_string(fp);
-		free_string(pRoomIndex->description);
-		pRoomIndex->description = fread_string(fp);
-		/* Area number */ fread_number(fp);
-		pRoomIndex->room_flags = fread_flag(fp);
+		free_read_string(pRoomIndex->name, fp);
+		free_read_string(pRoomIndex->description, fp);
+		/* Area number */ read_number(fp);
+		pRoomIndex->room_flags = read_flag(fp);
 		/* horrible hack */
 		if (3000 <= vnum && vnum < 3400)
 			SET_BIT(pRoomIndex->room_flags, ROOM_LAW);
-		pRoomIndex->sector_type = fread_number(fp);
+		pRoomIndex->sector_type = read_enum(sector_t, fp);
 		pRoomIndex->light = 0;
 		for (door = 0; door <= 5; door++)
 			pRoomIndex->exit[door] = NULL;
@@ -1018,16 +966,16 @@
 
 		for (;;)
 		{
-			letter = fread_letter(fp);
+			letter = read_letter(fp);
 
 			if (letter == 'S')
 				break;
 
 			if (letter == 'H')	/* healing room */
-				pRoomIndex->heal_rate = fread_number(fp);
+				pRoomIndex->heal_rate = read_number(fp);
 
 			else if (letter == 'M')	/* mana room */
-				pRoomIndex->mana_rate = fread_number(fp);
+				pRoomIndex->mana_rate = read_number(fp);
 
 			else if (letter == 'C')	/* clan */
 			{
@@ -1035,10 +983,10 @@
 
 				if (pRoomIndex->clan != NULL)
 				{
-					bug("Load_rooms: duplicate clan fields.", 0);
+					bug("Load_rooms: duplicate clan fields.");
 					exit(1);
 				}
-				tmp = fread_string(fp);
+				tmp = read_string(fp);
 				pRoomIndex->clan = clan_lookup(tmp);
 				free_string(tmp);
 				SET_BIT(pRoomIndex->room_flags, ROOM_NOEXPLORE);
@@ -1047,46 +995,51 @@
 			else if (letter == 'D')
 			{
 				EXIT_DATA *pexit;
-				int locks;
 
-				door = fread_number(fp);
+				door = read_number(fp);
 				if (door < 0 || door > 5)
 				{
-					bug("Fread_rooms: vnum %d has bad door number.", vnum);
+					bugf("Fread_rooms: vnum %ld has bad door number.", vnum);
 					exit(1);
 				}
 
 				pexit = new_exit();
-				free_string(pexit->description);
-				pexit->description = fread_string(fp);
-				free_string(pexit->keyword);
-				pexit->keyword = fread_string(fp);
+				free_read_string(pexit->description, fp);
+				free_read_string(pexit->keyword, fp);
 				pexit->exit_info = 0;
 				pexit->rs_flags = 0;	/* OLC */
-				locks = fread_number(fp);
-				pexit->key = fread_number(fp);
-				pexit->u1.vnum = fread_number(fp);
-				pexit->orig_door = door;	/* OLC */
-
-				switch (locks)
+				if (pRoomIndex->area->version < 2)
 				{
-				case 1:
-					pexit->exit_info = EX_ISDOOR;
-					pexit->rs_flags = EX_ISDOOR;
-					break;
-				case 2:
-					pexit->exit_info = EX_ISDOOR | EX_PICKPROOF;
-					pexit->rs_flags = EX_ISDOOR | EX_PICKPROOF;
-					break;
-				case 3:
-					pexit->exit_info = EX_ISDOOR | EX_NOPASS;
-					pexit->rs_flags = EX_ISDOOR | EX_NOPASS;
-					break;
-				case 4:
-					pexit->exit_info = EX_ISDOOR | EX_NOPASS | EX_PICKPROOF;
-					pexit->rs_flags = EX_ISDOOR | EX_NOPASS | EX_PICKPROOF;
-					break;
+					switch (read_number(fp))
+					{
+					case 1:
+						pexit->exit_info = EX_ISDOOR;
+						pexit->rs_flags = EX_ISDOOR;
+						break;
+					case 2:
+						pexit->exit_info = EX_ISDOOR | EX_PICKPROOF;
+						pexit->rs_flags = EX_ISDOOR | EX_PICKPROOF;
+						break;
+					case 3:
+						pexit->exit_info = EX_ISDOOR | EX_NOPASS;
+						pexit->rs_flags = EX_ISDOOR | EX_NOPASS;
+						break;
+					case 4:
+						pexit->exit_info = EX_ISDOOR | EX_NOPASS | EX_PICKPROOF;
+						pexit->rs_flags = EX_ISDOOR | EX_NOPASS | EX_PICKPROOF;
+						break;
+					}
 				}
+				else
+					pexit->rs_flags = read_flag(fp);
+
+				if (IS_SET(pexit->rs_flags, EX_TEMP))
+					REMOVE_BIT(pexit->rs_flags, EX_TEMP);
+
+				pexit->exit_info = pexit->rs_flags;
+				pexit->key = read_number(fp);
+				pexit->u1.vnum = read_number(fp);
+				pexit->orig_door = door;	/* OLC */
 
 				pRoomIndex->exit[door] = pexit;
 				top_exit++;
@@ -1096,10 +1049,8 @@
 				EXTRA_DESCR_DATA *ed;
 
 				ed = new_extra_descr();
-				free_string(ed->keyword);
-				ed->keyword = fread_string(fp);
-				free_string(ed->description);
-				ed->description = fread_string(fp);
+				free_read_string(ed->keyword, fp);
+				free_read_string(ed->description, fp);
 				LINK(ed, pRoomIndex->first_extra_descr,
 					 pRoomIndex->last_extra_descr, next, prev);
 				top_ed++;
@@ -1107,13 +1058,13 @@
 
 			else if (letter == 'O')
 			{
-				if (pRoomIndex->owner[0] != '\0')
+				if (!IS_NULLSTR(pRoomIndex->owner))
 				{
-					bug("Load_rooms: duplicate owner.", 0);
+					bug("Load_rooms: duplicate owner.");
 					exit(1);
 				}
 
-				pRoomIndex->owner = fread_string(fp);
+				pRoomIndex->owner = read_string(fp);
 				SET_BIT(pRoomIndex->room_flags, ROOM_NOEXPLORE);
 			}
 			else if (letter == 'R')
@@ -1123,23 +1074,22 @@
 				flag_t trigger = 0;
 
 				pRprog = new_prog();
-				word = fread_word(fp);
+				word = read_word(fp);
 				if ((trigger = flag_value(rprog_flags, word)) == NO_FLAG)
 				{
-					bug("ROOMprogs: invalid trigger.", 0);
+					bug("ROOMprogs: invalid trigger.");
 					exit(1);
 				}
 				SET_BIT(pRoomIndex->rprog_flags, trigger);
 				pRprog->trig_type = trigger;
-				pRprog->vnum = fread_number(fp);
-				free_string(pRprog->trig_phrase);
-				pRprog->trig_phrase = fread_string(fp);
+				pRprog->vnum = read_number(fp);
+				free_read_string(pRprog->trig_phrase, fp);
 				LINK(pRprog, pRoomIndex->first_rprog, pRoomIndex->last_rprog,
 					 next, prev);
 			}
 			else
 			{
-				bug("Load_rooms: vnum %d has flag not 'DES'.", vnum);
+				bugf("Load_rooms: vnum %ld has flag not 'DES'.", vnum);
 				exit(1);
 			}
 		}
@@ -1159,7 +1109,7 @@
 /*
  * Snarf a shop section.
  */
-void load_shops(FILE * fp)
+void load_shops(READ_DATA * fp)
 {
 	SHOP_DATA *pShop;
 
@@ -1169,16 +1119,16 @@
 		int iTrade;
 
 		pShop = new_shop();
-		pShop->keeper = fread_number(fp);
+		pShop->keeper = read_number(fp);
 		if (pShop->keeper == 0)
 			break;
 		for (iTrade = 0; iTrade < MAX_TRADE; iTrade++)
-			pShop->buy_type[iTrade] = fread_number(fp);
-		pShop->profit_buy = fread_number(fp);
-		pShop->profit_sell = fread_number(fp);
-		pShop->open_hour = fread_number(fp);
-		pShop->close_hour = fread_number(fp);
-		fread_to_eol(fp);
+			pShop->buy_type[iTrade] = read_number(fp);
+		pShop->profit_buy = read_number(fp);
+		pShop->profit_sell = read_number(fp);
+		pShop->open_hour = read_number(fp);
+		pShop->close_hour = read_number(fp);
+		read_to_eol(fp);
 		pMobIndex = get_mob_index(pShop->keeper);
 		pMobIndex->pShop = pShop;
 		LINK(pShop, shop_first, shop_last, next, prev);
@@ -1191,17 +1141,17 @@
 /*
  * Snarf spec proc declarations.
  */
-void load_specials(FILE * fp)
+void load_specials(READ_DATA * fp)
 {
 	for (;;)
 	{
 		MOB_INDEX_DATA *pMobIndex;
 		char letter;
 
-		switch (letter = fread_letter(fp))
+		switch (letter = read_letter(fp))
 		{
 		default:
-			bug("Load_specials: letter '%c' not *MS.", letter);
+			bugf("Load_specials: letter '%c' not *MS.", letter);
 			exit(1);
 
 		case 'S':
@@ -1211,17 +1161,17 @@
 			break;
 
 		case 'M':
-			pMobIndex = get_mob_index(fread_number(fp));
-			pMobIndex->spec_fun = spec_lookup(fread_word(fp));
+			pMobIndex = get_mob_index(read_number(fp));
+			pMobIndex->spec_fun = spec_lookup(read_word(fp));
 			if (pMobIndex->spec_fun == 0)
 			{
-				bug("Load_specials: 'M': vnum %d.", pMobIndex->vnum);
+				bugf("Load_specials: 'M': vnum %ld.", pMobIndex->vnum);
 				exit(1);
 			}
 			break;
 		}
 
-		fread_to_eol(fp);
+		read_to_eol(fp);
 	}
 }
 
@@ -1371,13 +1321,13 @@
 /*
  * Load mobprogs section
  */
-void load_mobprogs(FILE * fp)
+void load_mobprogs(READ_DATA * fp)
 {
 	PROG_CODE *pMprog;
 
 	if (current_area == NULL)
 	{
-		bug("Load_mobprogs: no #AREA seen yet.", 0);
+		bug("Load_mobprogs: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -1386,29 +1336,29 @@
 		vnum_t vnum;
 		char letter;
 
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		if (letter != '#')
 		{
-			bug("Load_mobprogs: # not found.", 0);
+			bug("Load_mobprogs: # not found.");
 			exit(1);
 		}
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (vnum == 0)
 			break;
 
-		fBootDb = FALSE;
+		run_level = RUNLEVEL_BOOT_NOEXIT;
 		if (get_prog_index(vnum, PRG_MPROG) != NULL)
 		{
-			bug("Load_mobprogs: vnum %d duplicated.", vnum);
+			bugf("Load_mobprogs: vnum %ld duplicated.", vnum);
 			exit(1);
 		}
-		fBootDb = TRUE;
+		run_level = RUNLEVEL_BOOTING;
 
 		pMprog = new_pcode();
 		pMprog->vnum = vnum;
-		free_string(pMprog->code);
-		pMprog->code = fread_string(fp);
+		free_read_string(pMprog->code, fp);
+		pMprog->area = current_area;
 		LINK(pMprog, mprog_first, mprog_last, next, prev);
 		top_mprog_index++;
 	}
@@ -1436,7 +1386,7 @@
 					replace_string(list->code, prog->code);
 				else
 				{
-					bug("Fix_mobprogs: code vnum %d not found.", list->vnum);
+					bugf("Fix_mobprogs: code vnum %ld not found.", list->vnum);
 					exit(1);
 				}
 			}
@@ -1553,19 +1503,19 @@
 		switch (pReset->command)
 		{
 		default:
-			bug("Reset_room: bad command %c.", pReset->command);
+			bugf("Reset_room: bad command %c.", pReset->command);
 			break;
 
 		case 'M':
 			if (!(pMobIndex = get_mob_index(pReset->arg1)))
 			{
-				bug("Reset_room: 'M': bad vnum %d.", pReset->arg1);
+				bugf("Reset_room: 'M': bad vnum %ld.", pReset->arg1);
 				continue;
 			}
 
 			if ((pRoomIndex = get_room_index(pReset->arg3)) == NULL)
 			{
-				bug("Reset_area: 'R': bad vnum %d.", pReset->arg3);
+				bugf("Reset_area: 'R': bad vnum %ld.", pReset->arg3);
 				continue;
 			}
 			if (pMobIndex->count >= pReset->arg2)
@@ -1622,19 +1572,19 @@
 		case 'O':
 			if (!(pObjIndex = get_obj_index(pReset->arg1)))
 			{
-				bug("Reset_room: 'O' 1 : bad vnum %d", pReset->arg1);
+				bugf("Reset_room: 'O' 1 : bad vnum %ld", pReset->arg1);
 				sprintf(buf, "%ld %d %ld %d", pReset->arg1,
 						pReset->arg2, pReset->arg3, pReset->arg4);
-				bug(buf, 1);
+				bugf(buf, 1);
 				continue;
 			}
 
 			if (!(pRoomIndex = get_room_index(pReset->arg3)))
 			{
-				bug("Reset_room: 'O' 2 : bad vnum %d.", pReset->arg3);
+				bugf("Reset_room: 'O' 2 : bad vnum %ld.", pReset->arg3);
 				sprintf(buf, "%ld %d %ld %d", pReset->arg1,
 						pReset->arg2, pReset->arg3, pReset->arg4);
-				bug(buf, 1);
+				bugf(buf, 1);
 				continue;
 			}
 
@@ -1656,13 +1606,13 @@
 		case 'P':
 			if (!(pObjIndex = get_obj_index(pReset->arg1)))
 			{
-				bug("Reset_room: 'P': bad vnum %d.", pReset->arg1);
+				bugf("Reset_room: 'P': bad vnum %ld.", pReset->arg1);
 				continue;
 			}
 
 			if (!(pObjToIndex = get_obj_index(pReset->arg3)))
 			{
-				bug("Reset_room: 'P': bad vnum %d.", pReset->arg3);
+				bugf("Reset_room: 'P': bad vnum %ld.", pReset->arg3);
 				continue;
 			}
 
@@ -1704,7 +1654,7 @@
 		case 'E':
 			if (!(pObjIndex = get_obj_index(pReset->arg1)))
 			{
-				bug("Reset_room: 'E' or 'G': bad vnum %d.", pReset->arg1);
+				bugf("Reset_room: 'E' or 'G': bad vnum %ld.", pReset->arg1);
 				continue;
 			}
 
@@ -1713,8 +1663,8 @@
 
 			if (!LastMob)
 			{
-				bug("Reset_room: 'E' or 'G': null mob for vnum %d.",
-					pReset->arg1);
+				bugf("Reset_room: 'E' or 'G': null mob for vnum %ld.",
+					 pReset->arg1);
 				last = FALSE;
 				break;
 			}
@@ -1807,7 +1757,7 @@
 
 			obj_to_char(pObj, LastMob);
 			if (pReset->command == 'E')
-				equip_char(LastMob, pObj, pReset->arg3);
+				equip_char(LastMob, pObj, (wloc_t) pReset->arg3);
 			last = TRUE;
 			break;
 
@@ -1817,7 +1767,7 @@
 		case 'R':
 			if (!(pRoomIndex = get_room_index(pReset->arg1)))
 			{
-				bug("Reset_room: 'R': bad vnum %d.", pReset->arg1);
+				bugf("Reset_room: 'R': bad vnum %ld.", pReset->arg1);
 				continue;
 			}
 
@@ -1826,12 +1776,23 @@
 				int d0;
 				int d1;
 
-				for (d0 = 0; d0 < pReset->arg2 - 1; d0++)
+				switch (pReset->arg3)
 				{
-					d1 = number_range(d0, pReset->arg2 - 1);
-					pExit = pRoomIndex->exit[d0];
-					pRoomIndex->exit[d0] = pRoomIndex->exit[d1];
-					pRoomIndex->exit[d1] = pExit;
+				default:
+					for (d0 = 0; d0 < pReset->arg2 - 1; d0++)
+					{
+						d1 = number_range(d0, pReset->arg2 - 1);
+						pExit = pRoomIndex->exit[d0];
+						pRoomIndex->exit[d0] = pRoomIndex->exit[d1];
+						pRoomIndex->exit[d1] = pExit;
+					}
+					break;
+				case 1:
+					add_random_exit(pRoomIndex, pReset, TRUE);
+					break;
+				case 2:
+					add_random_exit(pRoomIndex, pReset, FALSE);
+					break;
 				}
 			}
 			break;
@@ -1871,7 +1832,7 @@
 
 	if (pMobIndex == NULL)
 	{
-		bug("Create_mobile: NULL pMobIndex.", 0);
+		bug("Create_mobile: NULL pMobIndex.");
 		exit(1);
 	}
 
@@ -1960,6 +1921,12 @@
 		for (i = 0; i < MAX_STATS; i++)
 			mob->perm_stat[i] = UMIN(25, 11 + mob->level / 4);
 
+		{
+			int stance = number_range(STANCE_NORMAL, STANCE_SWALLOW);
+			SET_STANCE(mob, STANCE_CURRENT, STANCE_NONE);
+			SET_STANCE(mob, STANCE_AUTODROP, stance);
+		}
+
 		if (IS_SET(mob->act, ACT_WARRIOR))
 		{
 			mob->perm_stat[STAT_STR] += 3;
@@ -2110,11 +2077,11 @@
 		return;
 
 	/* start fixing values */
-	clone->name = str_dup(parent->name);
+	replace_string(clone->name, parent->name);
 	clone->version = parent->version;
-	clone->short_descr = str_dup(parent->short_descr);
-	clone->long_descr = str_dup(parent->long_descr);
-	clone->description = str_dup(parent->description);
+	replace_string(clone->short_descr, parent->short_descr);
+	replace_string(clone->long_descr, parent->long_descr);
+	replace_string(clone->description, parent->description);
 	clone->group = parent->group;
 	clone->sex = parent->sex;
 	for (i = 0; i < MAX_MCLASS; i++)
@@ -2151,7 +2118,7 @@
 	clone->form = parent->form;
 	clone->parts = parent->parts;
 	clone->size = parent->size;
-	clone->material = str_dup(parent->material);
+	replace_string(clone->material, parent->material);
 	clone->off_flags = parent->off_flags;
 	clone->dam_type = parent->dam_type;
 	clone->start_pos = parent->start_pos;
@@ -2187,7 +2154,7 @@
 
 	if (pObjIndex == NULL)
 	{
-		bug("Create_object: NULL pObjIndex.", 0);
+		bug("Create_object: NULL pObjIndex.");
 		exit(1);
 	}
 
@@ -2201,7 +2168,7 @@
 		obj->level = pObjIndex->level;
 	else
 		obj->level = UMAX(0, level);
-	obj->wear_loc = -1;
+	obj->wear_loc = WEAR_NONE;
 
 	obj->name = str_dup(pObjIndex->name);	/* OLC */
 	obj->short_descr = str_dup(pObjIndex->short_descr);	/* OLC */
@@ -2229,7 +2196,7 @@
 	switch (obj->item_type)
 	{
 	default:
-		bug("Read_object: vnum %d bad type.", pObjIndex->vnum);
+		bugf("Read_object: vnum %ld bad type.", pObjIndex->vnum);
 		break;
 
 	case ITEM_LIGHT:
@@ -2333,9 +2300,9 @@
 		return;
 
 	/* start fixing the object */
-	clone->name = str_dup(parent->name);
-	clone->short_descr = str_dup(parent->short_descr);
-	clone->description = str_dup(parent->description);
+	replace_string(clone->name, parent->name);
+	replace_string(clone->short_descr, parent->short_descr);
+	replace_string(clone->description, parent->description);
 	clone->item_type = parent->item_type;
 	clone->extra_flags = parent->extra_flags;
 	clone->wear_flags = parent->wear_flags;
@@ -2343,7 +2310,7 @@
 	clone->cost = parent->cost;
 	clone->level = parent->level;
 	clone->condition = parent->condition;
-	clone->material = str_dup(parent->material);
+	replace_string(clone->material, parent->material);
 	clone->timer = parent->timer;
 
 	for (i = 0; i < 5; i++)
@@ -2382,7 +2349,8 @@
 	ch->description = &str_empty[0];
 	ch->prompt = &str_empty[0];
 	ch->logon = current_time;
-	ch->lines = PAGELEN;
+	ch->lines = 0;
+	ch->columns = 0;
 	for (i = 0; i < 4; i++)
 		ch->armor[i] = 100;
 	ch->position = POS_STANDING;
@@ -2429,9 +2397,9 @@
 			return pMobIndex;
 	}
 
-	if (fBootDb)
+	if (run_level == RUNLEVEL_BOOTING)
 	{
-		bug("Get_mob_index: bad vnum %d.", vnum);
+		bugf("Get_mob_index: bad vnum %ld.", vnum);
 		exit(1);
 	}
 
@@ -2453,9 +2421,9 @@
 			return pObjIndex;
 	}
 
-	if (fBootDb)
+	if (run_level == RUNLEVEL_BOOTING)
 	{
-		bug("Get_obj_index: bad vnum %d.", vnum);
+		bugf("Get_obj_index: bad vnum %ld.", vnum);
 		exit(1);
 	}
 
@@ -2477,16 +2445,16 @@
 			return pRoomIndex;
 	}
 
-	if (fBootDb)
+	if (run_level == RUNLEVEL_BOOTING)
 	{
-		bug("Get_room_index: bad vnum %d.", vnum);
+		bugf("Get_room_index: bad vnum %ld.", vnum);
 		exit(1);
 	}
 
 	return NULL;
 }
 
-PROG_CODE *get_prog_index(vnum_t vnum, int type)
+PROG_CODE *get_prog_index(vnum_t vnum, prog_t type)
 {
 	PROG_CODE *prg;
 
@@ -2513,141 +2481,6 @@
 	return NULL;
 }
 
-/*
- * Read a letter from a file.
- */
-char fread_letter(FILE * fp)
-{
-	char c;
-
-	do
-	{
-		c = getc(fp);
-	}
-	while (isspace(c));
-
-	return c;
-}
-
-/*
- * Read a number from a file.
- */
-int fread_number(FILE * fp)
-{
-	int number;
-	bool sign;
-	char c;
-
-	do
-	{
-		c = getc(fp);
-	}
-	while (isspace(c));
-
-	number = 0;
-
-	sign = FALSE;
-	if (c == '+')
-	{
-		c = getc(fp);
-	}
-	else if (c == '-')
-	{
-		sign = TRUE;
-		c = getc(fp);
-	}
-
-	if (!isdigit(c))
-	{
-		bug("Fread_number: bad format.", 0);
-		exit(1);
-	}
-
-	while (isdigit(c))
-	{
-		number = number * 10 + c - '0';
-		c = getc(fp);
-	}
-
-	if (sign)
-		number = 0 - number;
-
-	if (c == '|')
-		number += fread_number(fp);
-	else if (c != ' ')
-		ungetc(c, fp);
-
-	return number;
-}
-
-flag_t fread_flag(FILE * fp)
-{
-	flag_t number, temp = 1;
-	flag_t flag;
-	char c;
-	bool negative = FALSE;
-
-	do
-	{
-		c = getc(fp);
-	}
-	while (isspace(c));
-
-	if (c != '+')
-	{
-		if (c == '-')
-		{
-			negative = TRUE;
-			c = getc(fp);
-		}
-
-		number = 0;
-
-		if (!isdigit(c))
-		{
-			while (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
-			{
-				number += flag_convert(c);
-				c = getc(fp);
-			}
-		}
-
-		while (isdigit(c))
-		{
-			number = number * 10 + c - '0';
-			c = getc(fp);
-		}
-
-		if (c == '|')
-			number += fread_flag(fp);
-
-		else if (c != ' ')
-			ungetc(c, fp);
-
-		if (negative)
-			return -1 * number;
-
-		return number;
-	}
-	else
-	{
-		number = 0;
-		flag = 0;
-		do
-		{
-			c = getc(fp);
-			flag += (temp << number) * (c == 'Y');
-			number++;
-		}
-		while (c == 'Y' || c == 'n');
-
-		if (c == '\n' || c == '\r')
-			ungetc(c, fp);
-
-		return flag;
-	}
-}
-
 flag_t flag_convert(char letter)
 {
 	flag_t bitsum = 0;
@@ -2670,410 +2503,29 @@
 }
 
 /*
- * Read and allocate space for a string from a file.
- * These strings are read-only and shared.
- * Strings are hashed:
- *   each string prepended with hash pointer to prev string,
- *   hash code is simply the string length.
- *   this function takes 40% to 50% of boot-up time.
- */
-const char *fread_string(FILE * fp)
-{
-#if (STRHASH==1)
-	char *plast;
-	char c;
-
-	plast = top_string + sizeof(char *);
-	if (plast > &string_space[MAX_STRING - MAX_STRING_LENGTH])
-	{
-		bug("Fread_string: MAX_STRING %d exceeded.", MAX_STRING);
-		exit(1);
-	}
-
-	/*
-	 * Skip blanks.
-	 * Read first char.
-	 */
-	do
-	{
-		c = getc(fp);
-	}
-	while (isspace(c));
-
-	if ((*plast++ = c) == '~')
-		return &str_empty[0];
-
-	for (;;)
-	{
-		/*
-		 * Back off the char type lookup,
-		 *   it was too dirty for portability.
-		 *   -- Furey
-		 */
-
-		switch (*plast = getc(fp))
-		{
-		default:
-			plast++;
-			break;
-
-		case EOF:
-			/* temp fix */
-			bug("Fread_string: EOF", 0);
-			return NULL;
-			/* exit( 1 ); */
-			break;
-
-		case '\n':
-			plast++;
-			*plast++ = '\r';
-			break;
-
-		case '\r':
-			break;
-
-		case '~':
-			plast++;
-			{
-				union
-				{
-					char *pc;
-					char rgc[sizeof(char *)];
-				}
-				u1;
-				unsigned int ic;
-				int iHash;
-				char *pHash;
-				char *pHashPrev;
-				char *pString;
-
-				plast[-1] = '\0';
-				iHash = UMIN(MAX_KEY_HASH - 1, plast - 1 - top_string);
-				for (pHash = string_hash[iHash]; pHash; pHash = pHashPrev)
-				{
-					for (ic = 0; ic < sizeof(char *); ic++)
-						u1.rgc[ic] = pHash[ic];
-					pHashPrev = u1.pc;
-					pHash += sizeof(char *);
-
-					if (top_string[sizeof(char *)] == pHash[0] &&
-						!str_casecmp(top_string + sizeof(char *) + 1,
-									 pHash + 1))
-						return pHash;
-				}
-
-				if (fBootDb)
-				{
-					pString = top_string;
-					top_string = plast;
-					u1.pc = string_hash[iHash];
-					for (ic = 0; ic < sizeof(char *); ic++)
-						pString[ic] = u1.rgc[ic];
-					string_hash[iHash] = pString;
-
-					nAllocString += 1;
-					sAllocString += top_string - pString;
-					return pString + sizeof(char *);
-				}
-				else
-				{
-					return str_dup(top_string + sizeof(char *));
-				}
-			}
-		}
-	}
-#else
-#define MLR	MSL*8
-	char buf[MLR + 2];			/* extra 2 bytes on the end for \0 and 1b slack */
-	char c;
-	long i = 0;
-	bool sFull = FALSE;
-
-	/* skip blanks */
-	do
-	{
-		c = getc(fp);
-	}
-	while (isspace(c));
-
-	/* empty string */
-	if (c == '~')
-		return &str_empty[0];
-
-	buf[i] = c;
-	i++;
-
-	for (;;)
-	{
-		if (i >= MLR && !sFull)
-		{
-			bugf("String [%20.20s...] exceeded [%d] MLR", buf, MLR);
-			sFull = TRUE;
-		}
-
-		switch (c = getc(fp))
-		{
-		default:
-			if (!sFull)
-			{
-				buf[i] = c;
-				i++;
-			}
-			break;
-
-		case EOF:
-			/* temp fix */
-			bugf("Fread_string: String [%20.20s...] EOF", buf);
-			return &str_empty[0];
-			break;
-
-		case '\n':
-			if (!sFull)
-			{
-				buf[i] = '\n';
-				i++;
-				buf[i] = '\r';
-				i++;
-			}
-			break;
-
-		case '\r':
-			break;
-
-		case '~':
-			buf[i] = '\0';
-			return str_dup(buf);
-			break;
-		}
-	}
-#endif
-}
-
-const char *freadline(FILE * fp)
-{
-	static char buf[MSL];
-	char c;
-	int pos = 0;
-
-	buf[0] = '\0';				/* reset strlen to 0 */
-
-	for (;;)
-	{
-		c = fgetc(fp);			/* get one char from file */
-		if (c == '\n' || c == '\r')	/* if CR or LF return the string */
-		{
-			return buf;			/* return the string */
-		}
-		else					/* else add one char to string */
-		{
-			buf[pos] = c;		/* insert c into string */
-			pos++;
-			buf[pos] = '\0';	/* add one char to string */
-		}
-
-		if (pos >= MSL)			/* check so we don't overflow */
-		{
-			buf[MSL] = '\0';	/* trim string to MSL */
-			ungetc(c, fp);		/* go 1 char back */
-			return buf;			/* return the string */
-		}
-	}
-	/* just in case - return empty string if we get somehow here */
-	buf[0] = '\0';
-	return buf;
-}
-
-/*
- * Read to end of line (for comments).
- */
-void fread_to_eol(FILE * fp)
-{
-	char c;
-
-	do
-	{
-		c = getc(fp);
-	}
-	while (c != '\n' && c != '\r');
-
-	do
-	{
-		c = getc(fp);
-	}
-	while (c == '\n' || c == '\r');
-
-	ungetc(c, fp);
-	return;
-}
-
-/*
- * Read one word (into static buffer).
- */
-char *fread_word(FILE * fp)
-{
-	static char word[MAX_INPUT_LENGTH];
-	char *pword;
-	char cEnd;
-
-	do
-	{
-		cEnd = getc(fp);
-	}
-	while (isspace(cEnd));
-
-	if (cEnd == '\'' || cEnd == '"')
-	{
-		pword = word;
-	}
-	else
-	{
-		word[0] = cEnd;
-		pword = word + 1;
-		cEnd = ' ';
-	}
-
-	for (; pword < word + MAX_INPUT_LENGTH; pword++)
-	{
-		*pword = getc(fp);
-		if (cEnd == ' ' ? isspace(*pword) : *pword == cEnd)
-		{
-			if (cEnd == ' ')
-				ungetc(*pword, fp);
-			*pword = '\0';
-			return word;
-		}
-	}
-
-	bug("Fread_word: word too long.", 0);
-	exit(1);
-	return NULL;
-}
-
-#if (STRHASH==2)
-
-#define MAX_STRING_HASH		(16*1024)
-
-typedef struct str str;
-struct str
-{
-	const char *p;
-	int ref;
-	str *next;
-};
-
-str *hash_str[MAX_STRING_HASH];
-
-#define strhash(s)	(hashstr(s, 64, MAX_STRING_HASH))
-
-/*
-** A simple and fast generic string hasher based on Peter K. Pearson's
-** article in CACM 33-6, pp. 677.
-*/
-
-static int TT[] = {
-	1, 87, 49, 12, 176, 178, 102, 166, 121, 193, 6, 84, 249, 230, 44, 163,
-	14, 197, 213, 181, 161, 85, 218, 80, 64, 239, 24, 226, 236, 142, 38, 200,
-	110, 177, 104, 103, 141, 253, 255, 50, 77, 101, 81, 18, 45, 96, 31, 222,
-	25, 107, 190, 70, 86, 237, 240, 34, 72, 242, 20, 214, 244, 227, 149, 235,
-	97, 234, 57, 22, 60, 250, 82, 175, 208, 5, 127, 199, 111, 62, 135, 248,
-	174, 169, 211, 58, 66, 154, 106, 195, 245, 171, 17, 187, 182, 179, 0, 243,
-	132, 56, 148, 75, 128, 133, 158, 100, 130, 126, 91, 13, 153, 246, 216, 219,
-	119, 68, 223, 78, 83, 88, 201, 99, 122, 11, 92, 32, 136, 114, 52, 10,
-	138, 30, 48, 183, 156, 35, 61, 26, 143, 74, 251, 94, 129, 162, 63, 152,
-	170, 7, 115, 167, 241, 206, 3, 150, 55, 59, 151, 220, 90, 53, 23, 131,
-	125, 173, 15, 238, 79, 95, 89, 16, 105, 137, 225, 224, 217, 160, 37, 123,
-	118, 73, 2, 157, 46, 116, 9, 145, 134, 228, 207, 212, 202, 215, 69, 229,
-	27, 188, 67, 124, 168, 252, 42, 4, 29, 108, 21, 247, 19, 205, 39, 203,
-	233, 40, 186, 147, 198, 192, 155, 33, 164, 191, 98, 204, 165, 180, 117, 76,
-	140, 36, 210, 172, 41, 54, 159, 8, 185, 232, 113, 196, 231, 47, 146, 120,
-	51, 65, 28, 144, 254, 221, 93, 189, 194, 139, 112, 43, 71, 109, 184, 209,
-};
-
-int hashstr(const char *s, int maxn, int hashs)
-{
-	register int h;
-	register unsigned char *p;
-	register int i;
-
-	for (h = 0, i = 0, p = (unsigned char *) s; *p && i < maxn; i++, p++)
-		h = TT[h ^ *p];
-	if (hashs > 256 && *s)
-	{
-		int oh = h;
-		for (i = 1, p = (unsigned char *) s, h = (*p++ + 1) & 0xff;
-			 *p && i < maxn; i++, p++)
-			h = TT[h ^ *p];
-		h += (oh << 8);
-	}
-	return h % hashs;			/* With 16 bit ints h has to be made positive first! */
-}
-static str *str_alloc(const char *p, int hash)
-{
-	str *s;
-
-	alloc_mem(s, str, 1);
-	s->ref = 0;
-	s->p = p;
-	s->next = hash_str[hash];
-	str_real_count++;
-	return hash_str[hash] = s;
-}
-
-static str *str_lookup(const char *p, int *hash)
-{
-	str *s;
-	for (s = hash_str[*hash = strhash(p)]; s; s = s->next)
-		if (!str_cmp(s->p, p))
-			return s;
-	return NULL;
-}
-#endif
-
-/*
  * Duplicate a string into dynamic memory.
  * Fread_strings are read-only and shared.
  */
 const char *str_dup(const char *pstr)
 {
 	char *str_new;
-#if (STRHASH==2)
-	int hash;
-	str *s;
-#endif
+	size_t size;
 
 	if (IS_NULLSTR(pstr))
 		return &str_empty[0];
 
-#if (STRHASH==1)
-	if (pstr >= string_space && pstr < top_string)
-		return pstr;
-#endif
+	size = strlen(pstr) + 1;
+	alloc_mem(str_new, char, size);
 
-#if STRHASH==2
-	str_count++;
-	if ((s = str_lookup(pstr, &hash)) == NULL)
-	{
-		alloc_mem(str_new, char, strlen(pstr) + 1);
-		if (str_new == NULL)
-		{
-			bug("Failed to grab memory for str_dup...", 0);
-			return &str_empty[0];
-		}
-		strcpy(str_new, pstr);
-		s = str_alloc(str_new, hash);
-	}
-	s->ref++;
-	return s->p;
-#else
-	alloc_mem(str_new, char, strlen(pstr) + 1);
 	if (str_new == NULL)
 	{
-		bug("Failed to grab memory for str_dup...", 0);
+		bug("Failed to grab memory for str_dup...");
 		return &str_empty[0];
 	}
 	strcpy(str_new, pstr);
+	sAllocString += size;
+	nAllocString += 1;
 	return str_new;
-#endif
 }
 
 /*
@@ -3081,43 +2533,14 @@
  * Null is legal here to simplify callers.
  * Read-only shared strings are not touched.
  */
-void free_string(const char *pstr)
+void _free_string(const char *pstr)
 {
-#if STRHASH==2
-	str *s, *q;
-	int hash;
-#endif
-
-	if (pstr == NULL || pstr == &str_empty[0]
-#if (STRHASH==1)
-		|| (pstr >= string_space && pstr < top_string)
-#endif
-		)
-		return;
-
-#if STRHASH==2
-	str_count--;
-	hash = strhash(pstr);
-	for (q = NULL, s = hash_str[hash]; s; s = s->next)
-	{
-		if (!str_cmp(s->p, pstr))
-			break;
-		q = s;
-	}
-
-	if (!s || --s->ref)
+	if (IS_NULLSTR(pstr))
 		return;
 
-	if (q)
-		q->next = s->next;
-	else
-		hash_str[hash] = hash_str[hash]->next;
-	str_real_count--;
-	free_mem(s->p);
-	free_mem(s);
-#else
+	sAllocString -= strlen(pstr);
+	nAllocString -= 1;
 	free_mem(pstr);
-#endif
 	return;
 }
 
@@ -3223,7 +2646,7 @@
 	int iArea;
 	int iAreaHalf;
 
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		chprintln(ch, "No argument is used with this command.");
 		return;
@@ -3279,12 +2702,12 @@
 	EXIT_DATA *pexit;
 	DESCRIPTOR_DATA *d;
 	AFFECT_DATA *af;
-	FILE *fp;
+	WRITE_DATA *fp;
 	vnum_t vnum;
 	int nMatch = 0;
 
 	/* open file */
-	fp = file_open("mem.dmp", "w");
+	fp = open_write(LOG_DIR "mem.dmp");
 
 	/* report use of data structures */
 
@@ -3292,7 +2715,7 @@
 	aff_count = 0;
 
 	/* mobile prototypes */
-	fprintf(fp, "MobProt	%4d (%8d bytes)\n", top_mob_index,
+	fprintf(fp->stream, "MobProt	%4d (%8d bytes)\n", top_mob_index,
 			top_mob_index * (sizeof(*pMobIndex)));
 
 	/* mobs */
@@ -3309,7 +2732,7 @@
 	for (fch = char_free; fch != NULL; fch = fch->next)
 		count2++;
 
-	fprintf(fp, "Mobs	%4d (%8d bytes), %2d free (%d bytes)\n", count,
+	fprintf(fp->stream, "Mobs	%4d (%8d bytes), %2d free (%d bytes)\n", count,
 			count * (sizeof(*fch)), count2, count2 * (sizeof(*fch)));
 
 	/* pcdata */
@@ -3317,7 +2740,7 @@
 	for (pc = pcdata_free; pc != NULL; pc = pc->next)
 		count++;
 
-	fprintf(fp, "Pcdata	%4d (%8d bytes), %2d free (%d bytes)\n",
+	fprintf(fp->stream, "Pcdata	%4d (%8d bytes), %2d free (%d bytes)\n",
 			num_pcs, num_pcs * (sizeof(*pc)), count, count * (sizeof(*pc)));
 
 	/* descriptors */
@@ -3328,7 +2751,7 @@
 	for (d = descriptor_free; d != NULL; d = d->next)
 		count2++;
 
-	fprintf(fp, "Descs	%4d (%8d bytes), %2d free (%d bytes)\n", count,
+	fprintf(fp->stream, "Descs	%4d (%8d bytes), %2d free (%d bytes)\n", count,
 			count * (sizeof(*d)), count2, count2 * (sizeof(*d)));
 
 	/* object prototypes */
@@ -3340,7 +2763,7 @@
 			nMatch++;
 		}
 
-	fprintf(fp, "ObjProt	%4d (%8d bytes)\n", top_obj_index,
+	fprintf(fp->stream, "ObjProt	%4d (%8d bytes)\n", top_obj_index,
 			top_obj_index * (sizeof(*pObjIndex)));
 
 	/* objects */
@@ -3355,7 +2778,7 @@
 	for (obj = obj_free; obj != NULL; obj = obj->next)
 		count2++;
 
-	fprintf(fp, "Objs	%4d (%8d bytes), %2d free (%d bytes)\n", count,
+	fprintf(fp->stream, "Objs	%4d (%8d bytes), %2d free (%d bytes)\n", count,
 			count * (sizeof(*obj)), count2, count2 * (sizeof(*obj)));
 
 	/* affects */
@@ -3363,52 +2786,52 @@
 	for (af = affect_free; af != NULL; af = af->next)
 		count++;
 
-	fprintf(fp, "Affects	%4d (%8d bytes), %2d free (%d bytes)\n",
+	fprintf(fp->stream, "Affects	%4d (%8d bytes), %2d free (%d bytes)\n",
 			aff_count, aff_count * (sizeof(*af)), count, count * (sizeof(*af)));
 
 	/* rooms */
-	fprintf(fp, "Rooms	%4d (%8d bytes)\n", top_room,
+	fprintf(fp->stream, "Rooms	%4d (%8d bytes)\n", top_room,
 			top_room * (sizeof(*room)));
 
 	/* exits */
-	fprintf(fp, "Exits	%4d (%8d bytes)\n", top_exit,
+	fprintf(fp->stream, "Exits	%4d (%8d bytes)\n", top_exit,
 			top_exit * (sizeof(*pexit)));
 
-	file_close(fp);
+	close_write(fp);
 
 	/* start printing out mobile data */
-	fp = file_open("mob.dmp", "w");
+	fp = open_write(LOG_DIR "mob.dmp");
 
-	fprintf(fp, "\nMobile Analysis\n");
-	fprintf(fp, "---------------\n");
+	fprintf(fp->stream, "\nMobile Analysis\n");
+	fprintf(fp->stream, "---------------\n");
 	nMatch = 0;
 	for (vnum = 0; nMatch < top_mob_index; vnum++)
 		if ((pMobIndex = get_mob_index(vnum)) != NULL)
 		{
 			nMatch++;
-			fprintf(fp, "#%-4ld %3d active %3d killed     %s\n",
+			fprintf(fp->stream, "#%-4ld %3d active %3d killed     %s\n",
 					pMobIndex->vnum, pMobIndex->count, pMobIndex->killed,
 					pMobIndex->short_descr);
 		}
-	file_close(fp);
+	close_write(fp);
 
 	/* start printing out object data */
-	fp = file_open("obj.dmp", "w");
+	fp = open_write(LOG_DIR "obj.dmp");
 
-	fprintf(fp, "\nObject Analysis\n");
-	fprintf(fp, "---------------\n");
+	fprintf(fp->stream, "\nObject Analysis\n");
+	fprintf(fp->stream, "---------------\n");
 	nMatch = 0;
 	for (vnum = 0; nMatch < top_obj_index; vnum++)
 		if ((pObjIndex = get_obj_index(vnum)) != NULL)
 		{
 			nMatch++;
-			fprintf(fp, "#%-4ld %3d active %3d reset      %s\n",
+			fprintf(fp->stream, "#%-4ld %3d active %3d reset      %s\n",
 					pObjIndex->vnum, pObjIndex->count,
 					pObjIndex->reset_num, pObjIndex->short_descr);
 		}
 
 	/* close file */
-	file_close(fp);
+	close_write(fp);
 }
 
 #if defined(WIN32)
@@ -3684,13 +3107,13 @@
 {
 	if (astr == NULL)
 	{
-		bug("Str_prefix: null astr.", 0);
+		bug("Str_prefix: null astr.");
 		return TRUE;
 	}
 
 	if (bstr == NULL)
 	{
-		bug("Str_prefix: null bstr.", 0);
+		bug("Str_prefix: null bstr.");
 		return TRUE;
 	}
 
@@ -3768,21 +3191,21 @@
  */
 void append_file(CHAR_DATA * ch, char *file, const char *str)
 {
-	FILE *fp;
+	WRITE_DATA *fp;
 
-	if (IS_NPC(ch) || str[0] == '\0')
+	if (IS_NPC(ch) || IS_NULLSTR(str))
 		return;
 
-	if ((fp = file_open(file, "a")) == NULL)
+	if ((fp = open_append(file)) == NULL)
 	{
-		perror(file);
+		log_error(file);
 		chprintln(ch, "Could not open the file!");
 	}
 	else
 	{
-		fprintf(fp, "[%5ld] %s: %s\n",
+		fprintf(fp->stream, "[%5ld] %s: %s\n",
 				ch->in_room ? ch->in_room->vnum : 0, ch->name, str);
-		file_close(fp);
+		close_append(fp);
 	}
 
 	return;
@@ -3791,53 +3214,28 @@
 /*
  * Reports a bug.
  */
-void bug(const char *str, int param)
+void bug(const char *str)
 {
 	char buf[MAX_STRING_LENGTH];
 
 	if (fpArea != NULL)
 	{
-		int iLine;
-		int iChar;
+		size_t iLine;
+		int iCount = 0;
 
-		if (fpArea == stdin)
-		{
-			iLine = 0;
-		}
-		else
+		for (iLine = 0; iLine < UMIN(fpArea->pos, fpArea->size); iLine++)
 		{
-			iChar = ftell(fpArea);
-			fseek(fpArea, 0, 0);
-			for (iLine = 0; ftell(fpArea) < iChar; iLine++)
-			{
-				while (getc(fpArea) != '\n')
-					;
-			}
-			fseek(fpArea, iChar, 0);
+			if (fpArea->str[iLine] == '\n')
+				iCount++;
 		}
 
-		sprintf(buf, "[*****] FILE: %s LINE: %d", strArea, iLine);
+		sprintf(buf, "[*****] FILE: %s LINE: %d", strArea, iCount);
 		log_string(buf);
-/* RT removed because we don't want bugs shutting the mud 
-	if ( ( fp = file_open( "shutdown.txt", "a" ) ) != NULL )
-	{
-	    fprintf( fp, "[*****] %s\n", buf );
-	    file_close( fp );
-	}
-*/
 	}
 
-	strcpy(buf, "[*****] BUG: ");
-	sprintf(buf + strlen(buf), str, param);
+	sprintf(buf, "[*****] BUG: %s", str);
 	log_string(buf);
-/* RT removed due to bug-file spamming 
-    if ( ( fp = file_open( BUG_FILE, "a" ) ) != NULL )
-    {
-	fprintf( fp, "%s\n", buf );
-	file_close( fp );
-    }
-*/
-
+	wiznet(buf, NULL, NULL, WIZ_BUGS, 0, 0);
 	return;
 }
 
@@ -3846,7 +3244,16 @@
  */
 void log_string(const char *str)
 {
-	fprintf(stderr, "%s :: %s\n", str_time(current_time, -1, NULL), str);
+	fprintf(stderr, "%s :: %s\n", str_time(-1, -1, NULL), str);
+	return;
+}
+
+void log_error(const char *str)
+{
+	char buf[MSL];
+
+	sprintf(buf, "%s :: %s", str_time(-1, -1, NULL), str);
+	perror(buf);
 	return;
 }
 
diff -ur -x config -x o -x rom src/db.h new/db.h
--- src/db.h	Tue May 27 02:46:36 2003
+++ new/db.h	Sun Aug 31 19:23:21 2003
@@ -22,34 +22,27 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
 #if !defined(DB_H)
 #define DB_H
 
-#if (STRHASH==1)
-#define			MAX_STRING	    4000*1024
-#endif
-
 /* conversion from db.h */
-void convert_mob(MOB_INDEX_DATA * mob);
-void convert_obj(OBJ_INDEX_DATA * obj);
-
-void strspace_alloc();
+PROTOTYPE(void convert_mob, (MOB_INDEX_DATA *));
+PROTOTYPE(void convert_obj, (OBJ_INDEX_DATA *));
 
 /* macro for flag swapping */
 #define GET_UNSET(flag1,flag2)	(~(flag1)&((flag1)|(flag2)))
 
 /* func from db.c */
-extern void assign_area_vnum(vnum_t vnum);	/* OLC */
+PROTOTYPE(void assign_area_vnum, (vnum_t));	/* OLC */
 
 /* from db2.c */
 
-void convert_mobile(MOB_INDEX_DATA * pMobIndex);	/* OLC ROM */
-void convert_objects(void);		/* OLC ROM */
-void convert_object(OBJ_INDEX_DATA * pObjIndex);	/* OLC ROM */
-void load_bank_data args((void));
+PROTOTYPE(void convert_mobile, (MOB_INDEX_DATA *));	/* OLC ROM */
+PROTOTYPE(void convert_objects, (void));	/* OLC ROM */
+PROTOTYPE(void convert_object, (OBJ_INDEX_DATA *));	/* OLC ROM */
 
 #endif
diff -ur -x config -x o -x rom src/db2.c new/db2.c
--- src/db2.c	Tue May 27 02:46:35 2003
+++ new/db2.c	Sun Aug 31 19:23:20 2003
@@ -22,21 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-#include <stdarg.h>
 #include "merc.h"
 #include "db.h"
 #include "tables.h"
@@ -46,25 +35,24 @@
 #include "recycle.h"
 #include "olc.h"
 #include "webserver.h"
+#include "save.h"
 
 /* values for db2.c */
 
-extern AREA_DATA *current_area;
-int top_oprog_index;
-int top_rprog_index;
+EXTERN AREA_DATA *current_area;
 int nAllocPerm;
 long sAllocPerm;
 
 /*
  * Snarf a mob section.  new style
  */
-void load_mobiles(FILE * fp)
+void load_mobiles(READ_DATA * fp)
 {
 	MOB_INDEX_DATA *pMobIndex;
 
 	if (!current_area)			/* OLC */
 	{
-		bug("Load_mobiles: no #AREA seen yet.", 0);
+		bug("Load_mobiles: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -75,110 +63,108 @@
 		int iHash;
 		const char *tmp;
 
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		if (letter != '#')
 		{
-			bug("Load_mobiles: # not found.", 0);
+			bug("Load_mobiles: # not found.");
 			exit(1);
 		}
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (vnum == 0)
 			break;
 
-		fBootDb = FALSE;
+		run_level = RUNLEVEL_BOOT_NOEXIT;
 		if (get_mob_index(vnum) != NULL)
 		{
-			bug("Load_mobiles: vnum %d duplicated.", vnum);
+			bugf("Load_mobiles: vnum %ld duplicated.", vnum);
 			exit(1);
 		}
-		fBootDb = TRUE;
+		run_level = RUNLEVEL_BOOTING;
 
 		pMobIndex = new_mob_index();
 		pMobIndex->vnum = vnum;
 		pMobIndex->area = current_area;	/* OLC */
 		pMobIndex->new_format = TRUE;
 		newmobs++;
-		free_string(pMobIndex->player_name);
-		pMobIndex->player_name = fread_string(fp);
-		free_string(pMobIndex->short_descr);
-		pMobIndex->short_descr = fread_string(fp);
-		free_string(pMobIndex->long_descr);
-		pMobIndex->long_descr = fread_string(fp);
-		free_string(pMobIndex->description);
-		pMobIndex->description = fread_string(fp);
-		tmp = fread_string(fp);
+		free_read_string(pMobIndex->player_name, fp);
+		free_read_string(pMobIndex->short_descr, fp);
+		free_read_string(pMobIndex->long_descr, fp);
+		free_read_string(pMobIndex->description, fp);
+		tmp = read_string(fp);
 		pMobIndex->race = race_lookup(tmp);
 		free_string(tmp);
+		if (pMobIndex->race == NULL)
+			pMobIndex->race = default_race;
 
-		pMobIndex->act = fread_flag(fp) | ACT_IS_NPC | pMobIndex->race->act;
-		pMobIndex->affected_by = fread_flag(fp) | pMobIndex->race->aff;
+		pMobIndex->act = read_flag(fp) | ACT_IS_NPC | pMobIndex->race->act;
+		pMobIndex->affected_by = read_flag(fp) | pMobIndex->race->aff;
 		pMobIndex->pShop = NULL;
-		pMobIndex->alignment = fread_number(fp);
-		pMobIndex->group = fread_number(fp);
+		pMobIndex->alignment = read_number(fp);
+		pMobIndex->group = read_number(fp);
 
-		pMobIndex->level = fread_number(fp);
-		pMobIndex->hitroll = fread_number(fp);
+		pMobIndex->level = read_number(fp);
+		pMobIndex->hitroll = read_number(fp);
 
 		/* read hit dice */
-		pMobIndex->hit[DICE_NUMBER] = fread_number(fp);
-		/* 'd'          */ fread_letter(fp);
-		pMobIndex->hit[DICE_TYPE] = fread_number(fp);
-		/* '+'          */ fread_letter(fp);
-		pMobIndex->hit[DICE_BONUS] = fread_number(fp);
+		pMobIndex->hit[DICE_NUMBER] = read_number(fp);
+		/* 'd'          */ read_letter(fp);
+		pMobIndex->hit[DICE_TYPE] = read_number(fp);
+		/* '+'          */ read_letter(fp);
+		pMobIndex->hit[DICE_BONUS] = read_number(fp);
 
 		/* read mana dice */
-		pMobIndex->mana[DICE_NUMBER] = fread_number(fp);
-		fread_letter(fp);
-		pMobIndex->mana[DICE_TYPE] = fread_number(fp);
-		fread_letter(fp);
-		pMobIndex->mana[DICE_BONUS] = fread_number(fp);
+		pMobIndex->mana[DICE_NUMBER] = read_number(fp);
+		read_letter(fp);
+		pMobIndex->mana[DICE_TYPE] = read_number(fp);
+		read_letter(fp);
+		pMobIndex->mana[DICE_BONUS] = read_number(fp);
 
 		/* read damage dice */
-		pMobIndex->damage[DICE_NUMBER] = fread_number(fp);
-		fread_letter(fp);
-		pMobIndex->damage[DICE_TYPE] = fread_number(fp);
-		fread_letter(fp);
-		pMobIndex->damage[DICE_BONUS] = fread_number(fp);
-		pMobIndex->dam_type = attack_lookup(fread_word(fp));
+		pMobIndex->damage[DICE_NUMBER] = read_number(fp);
+		read_letter(fp);
+		pMobIndex->damage[DICE_TYPE] = read_number(fp);
+		read_letter(fp);
+		pMobIndex->damage[DICE_BONUS] = read_number(fp);
+		pMobIndex->dam_type = attack_lookup(read_word(fp));
 
 		/* read armor class */
-		pMobIndex->ac[AC_PIERCE] = fread_number(fp) * 10;
-		pMobIndex->ac[AC_BASH] = fread_number(fp) * 10;
-		pMobIndex->ac[AC_SLASH] = fread_number(fp) * 10;
-		pMobIndex->ac[AC_EXOTIC] = fread_number(fp) * 10;
+		pMobIndex->ac[AC_PIERCE] = read_number(fp) * 10;
+		pMobIndex->ac[AC_BASH] = read_number(fp) * 10;
+		pMobIndex->ac[AC_SLASH] = read_number(fp) * 10;
+		pMobIndex->ac[AC_EXOTIC] = read_number(fp) * 10;
 
 		/* read flags and add in data from the race table */
-		pMobIndex->off_flags = fread_flag(fp) | pMobIndex->race->off;
-		pMobIndex->imm_flags = fread_flag(fp) | pMobIndex->race->imm;
-		pMobIndex->res_flags = fread_flag(fp) | pMobIndex->race->res;
-		pMobIndex->vuln_flags = fread_flag(fp) | pMobIndex->race->vuln;
+		pMobIndex->off_flags = read_flag(fp) | pMobIndex->race->off;
+		pMobIndex->imm_flags = read_flag(fp) | pMobIndex->race->imm;
+		pMobIndex->res_flags = read_flag(fp) | pMobIndex->race->res;
+		pMobIndex->vuln_flags = read_flag(fp) | pMobIndex->race->vuln;
 
 		/* vital statistics */
-		pMobIndex->start_pos = position_lookup(fread_word(fp));
-		pMobIndex->default_pos = position_lookup(fread_word(fp));
-		pMobIndex->sex = sex_lookup(fread_word(fp));
+		pMobIndex->start_pos = position_lookup(read_word(fp));
+		pMobIndex->default_pos = position_lookup(read_word(fp));
+		pMobIndex->sex = sex_lookup(read_word(fp));
 
-		pMobIndex->wealth = fread_number(fp);
+		pMobIndex->wealth = read_number(fp);
 
-		pMobIndex->form = fread_flag(fp) | pMobIndex->race->form;
-		pMobIndex->parts = fread_flag(fp) | pMobIndex->race->parts;
+		pMobIndex->form = read_flag(fp) | pMobIndex->race->form;
+		pMobIndex->parts = read_flag(fp) | pMobIndex->race->parts;
 		/* size */
-		CHECK_POS(pMobIndex->size, size_lookup(fread_word(fp)), "size");
-/*	pMobIndex->size			= size_lookup(fread_word(fp)); */
-		pMobIndex->material = str_dup(fread_word(fp));
+		CHECK_POS(pMobIndex->size, size_lookup(read_word(fp)), "size");
+/*	pMobIndex->size			= size_lookup(read_word(fp)); */
+		pMobIndex->material = str_dup(read_word(fp));
 
 		for (;;)
 		{
-			letter = fread_letter(fp);
+			letter = read_letter(fp);
 
 			if (letter == 'F')
 			{
 				char *word;
 				flag_t vector;
 
-				word = fread_word(fp);
-				vector = fread_flag(fp);
+				word = read_word(fp);
+				vector = read_flag(fp);
 
 				if (!str_prefix(word, "act"))
 					REMOVE_BIT(pMobIndex->act, vector);
@@ -198,7 +184,7 @@
 					REMOVE_BIT(pMobIndex->parts, vector);
 				else
 				{
-					bug("Flag remove: flag not found.", 0);
+					bug("Flag remove: flag not found.");
 					exit(1);
 				}
 			}
@@ -209,23 +195,22 @@
 				int trigger = 0;
 
 				pMprog = new_prog();
-				word = fread_word(fp);
+				word = read_word(fp);
 				if ((trigger = flag_value(mprog_flags, word)) == NO_FLAG)
 				{
-					bug("MOBprogs: invalid trigger.", 0);
+					bug("MOBprogs: invalid trigger.");
 					exit(1);
 				}
 				SET_BIT(pMobIndex->mprog_flags, trigger);
 				pMprog->trig_type = trigger;
-				pMprog->vnum = fread_number(fp);
-				free_string(pMprog->trig_phrase);
-				pMprog->trig_phrase = fread_string(fp);
+				pMprog->vnum = read_number(fp);
+				free_read_string(pMprog->trig_phrase, fp);
 				LINK(pMprog, pMobIndex->first_mprog, pMobIndex->last_mprog,
 					 next, prev);
 			}
 			else
 			{
-				ungetc(letter, fp);
+				fp->pos--;
 				break;
 			}
 		}
@@ -244,13 +229,13 @@
 /*
  * Snarf an obj section. new style
  */
-void load_objects(FILE * fp)
+void load_objects(READ_DATA * fp)
 {
 	OBJ_INDEX_DATA *pObjIndex;
 
 	if (!current_area)			/* OLC */
 	{
-		bug("Load_objects: no #AREA seen yet.", 0);
+		bug("Load_objects: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -260,24 +245,24 @@
 		char letter;
 		int iHash;
 
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		if (letter != '#')
 		{
-			bug("Load_objects: # not found.", 0);
+			bug("Load_objects: # not found.");
 			exit(1);
 		}
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (vnum == 0)
 			break;
 
-		fBootDb = FALSE;
+		run_level = RUNLEVEL_BOOT_NOEXIT;
 		if (get_obj_index(vnum) != NULL)
 		{
-			bug("Load_objects: vnum %d duplicated.", vnum);
+			bugf("Load_objects: vnum %ld duplicated.", vnum);
 			exit(1);
 		}
-		fBootDb = TRUE;
+		run_level = RUNLEVEL_BOOTING;
 
 		pObjIndex = new_obj_index();
 		pObjIndex->vnum = vnum;
@@ -285,75 +270,71 @@
 		pObjIndex->new_format = TRUE;
 		pObjIndex->reset_num = 0;
 		newobjs++;
-		free_string(pObjIndex->name);
-		pObjIndex->name = fread_string(fp);
-		free_string(pObjIndex->short_descr);
-		pObjIndex->short_descr = fread_string(fp);
-		free_string(pObjIndex->description);
-		pObjIndex->description = fread_string(fp);
-		free_string(pObjIndex->material);
-		pObjIndex->material = fread_string(fp);
+		free_read_string(pObjIndex->name, fp);
+		free_read_string(pObjIndex->short_descr, fp);
+		free_read_string(pObjIndex->description, fp);
+		free_read_string(pObjIndex->material, fp);
 
-		CHECK_POS(pObjIndex->item_type, item_lookup(fread_word(fp)),
+		CHECK_POS(pObjIndex->item_type, item_lookup(read_word(fp)),
 				  "item_type");
-		pObjIndex->extra_flags = fread_flag(fp);
-		pObjIndex->wear_flags = fread_flag(fp);
+		pObjIndex->extra_flags = read_flag(fp);
+		pObjIndex->wear_flags = read_flag(fp);
 		switch (pObjIndex->item_type)
 		{
 		case ITEM_WEAPON:
-			pObjIndex->value[0] = weapon_typ(fread_word(fp));
-			pObjIndex->value[1] = fread_number(fp);
-			pObjIndex->value[2] = fread_number(fp);
-			pObjIndex->value[3] = attack_lookup(fread_word(fp));
-			pObjIndex->value[4] = fread_flag(fp);
+			pObjIndex->value[0] = weapon_typ(read_word(fp));
+			pObjIndex->value[1] = read_number(fp);
+			pObjIndex->value[2] = read_number(fp);
+			pObjIndex->value[3] = attack_lookup(read_word(fp));
+			pObjIndex->value[4] = read_flag(fp);
 			break;
 		case ITEM_CONTAINER:
-			pObjIndex->value[0] = fread_number(fp);
-			pObjIndex->value[1] = fread_flag(fp);
-			pObjIndex->value[2] = fread_number(fp);
-			pObjIndex->value[3] = fread_number(fp);
-			pObjIndex->value[4] = fread_number(fp);
+			pObjIndex->value[0] = read_number(fp);
+			pObjIndex->value[1] = read_flag(fp);
+			pObjIndex->value[2] = read_number(fp);
+			pObjIndex->value[3] = read_number(fp);
+			pObjIndex->value[4] = read_number(fp);
 			break;
 		case ITEM_DRINK_CON:
 		case ITEM_FOUNTAIN:
-			pObjIndex->value[0] = fread_number(fp);
-			pObjIndex->value[1] = fread_number(fp);
+			pObjIndex->value[0] = read_number(fp);
+			pObjIndex->value[1] = read_number(fp);
 			CHECK_POS(pObjIndex->value[2],
-					  liq_lookup(fread_word(fp)), "liq_lookup");
-			pObjIndex->value[3] = fread_number(fp);
-			pObjIndex->value[4] = fread_number(fp);
+					  liq_lookup(read_word(fp)), "liq_lookup");
+			pObjIndex->value[3] = read_number(fp);
+			pObjIndex->value[4] = read_number(fp);
 			break;
 		case ITEM_WAND:
 		case ITEM_STAFF:
-			pObjIndex->value[0] = fread_number(fp);
-			pObjIndex->value[1] = fread_number(fp);
-			pObjIndex->value[2] = fread_number(fp);
-			pObjIndex->value[3] = skill_lookup(fread_word(fp));
-			pObjIndex->value[4] = fread_number(fp);
+			pObjIndex->value[0] = read_number(fp);
+			pObjIndex->value[1] = read_number(fp);
+			pObjIndex->value[2] = read_number(fp);
+			pObjIndex->value[3] = skill_lookup(read_word(fp));
+			pObjIndex->value[4] = read_number(fp);
 			break;
 		case ITEM_POTION:
 		case ITEM_PILL:
 		case ITEM_SCROLL:
-			pObjIndex->value[0] = fread_number(fp);
-			pObjIndex->value[1] = skill_lookup(fread_word(fp));
-			pObjIndex->value[2] = skill_lookup(fread_word(fp));
-			pObjIndex->value[3] = skill_lookup(fread_word(fp));
-			pObjIndex->value[4] = skill_lookup(fread_word(fp));
+			pObjIndex->value[0] = read_number(fp);
+			pObjIndex->value[1] = skill_lookup(read_word(fp));
+			pObjIndex->value[2] = skill_lookup(read_word(fp));
+			pObjIndex->value[3] = skill_lookup(read_word(fp));
+			pObjIndex->value[4] = skill_lookup(read_word(fp));
 			break;
 		default:
-			pObjIndex->value[0] = fread_flag(fp);
-			pObjIndex->value[1] = fread_flag(fp);
-			pObjIndex->value[2] = fread_flag(fp);
-			pObjIndex->value[3] = fread_flag(fp);
-			pObjIndex->value[4] = fread_flag(fp);
+			pObjIndex->value[0] = read_flag(fp);
+			pObjIndex->value[1] = read_flag(fp);
+			pObjIndex->value[2] = read_flag(fp);
+			pObjIndex->value[3] = read_flag(fp);
+			pObjIndex->value[4] = read_flag(fp);
 			break;
 		}
-		pObjIndex->level = fread_number(fp);
-		pObjIndex->weight = fread_number(fp);
-		pObjIndex->cost = fread_number(fp);
+		pObjIndex->level = read_number(fp);
+		pObjIndex->weight = read_number(fp);
+		pObjIndex->cost = read_number(fp);
 
 		/* condition */
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		switch (letter)
 		{
 		case ('P'):
@@ -386,7 +367,7 @@
 		{
 			char pletter;
 
-			pletter = fread_letter(fp);
+			pletter = read_letter(fp);
 
 			if (pletter == 'A')
 			{
@@ -397,8 +378,8 @@
 				paf->type = -1;
 				paf->level = pObjIndex->level;
 				paf->duration = -1;
-				paf->location = fread_number(fp);
-				paf->modifier = fread_number(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->modifier = read_number(fp);
 				paf->bitvector = 0;
 				LINK(paf, pObjIndex->first_affect, pObjIndex->last_affect, next,
 					 prev);
@@ -410,7 +391,7 @@
 				AFFECT_DATA *paf;
 
 				paf = new_affect();
-				pletter = fread_letter(fp);
+				pletter = read_letter(fp);
 				switch (pletter)
 				{
 				case 'A':
@@ -426,15 +407,15 @@
 					paf->where = TO_VULN;
 					break;
 				default:
-					bug("Load_objects: Bad where on flag set.", 0);
+					bug("Load_objects: Bad where on flag set.");
 					exit(1);
 				}
 				paf->type = -1;
 				paf->level = pObjIndex->level;
 				paf->duration = -1;
-				paf->location = fread_number(fp);
-				paf->modifier = fread_number(fp);
-				paf->bitvector = fread_flag(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->modifier = read_number(fp);
+				paf->bitvector = read_flag(fp);
 				LINK(paf, pObjIndex->first_affect, pObjIndex->last_affect, next,
 					 prev);
 				top_affect++;
@@ -445,10 +426,8 @@
 				EXTRA_DESCR_DATA *ed;
 
 				ed = new_extra_descr();
-				free_string(ed->keyword);
-				ed->keyword = fread_string(fp);
-				free_string(ed->description);
-				ed->description = fread_string(fp);
+				free_read_string(ed->keyword, fp);
+				free_read_string(ed->description, fp);
 				LINK(ed, pObjIndex->first_extra_descr,
 					 pObjIndex->last_extra_descr, next, prev);
 				top_ed++;
@@ -460,24 +439,23 @@
 				flag_t trigger = 0;
 
 				pOprog = new_prog();
-				word = fread_word(fp);
+				word = read_word(fp);
 				if ((trigger = flag_value(oprog_flags, word)) == NO_FLAG)
 				{
-					bug("OBJprogs: invalid trigger.", 0);
+					bug("OBJprogs: invalid trigger.");
 					exit(1);
 				}
 				SET_BIT(pObjIndex->oprog_flags, trigger);
 				pOprog->trig_type = trigger;
-				pOprog->vnum = fread_number(fp);
-				free_string(pOprog->trig_phrase);
-				pOprog->trig_phrase = fread_string(fp);
+				pOprog->vnum = read_number(fp);
+				free_read_string(pOprog->trig_phrase, fp);
 				LINK(pOprog, pObjIndex->first_oprog, pObjIndex->last_oprog,
 					 next, prev);
 			}
 
 			else
 			{
-				ungetc(pletter, fp);
+				fp->pos--;
 				break;
 			}
 		}
@@ -528,13 +506,15 @@
 				{
 				case 'M':
 					if (!(pMob = get_mob_index(pReset->arg1)))
-						bug("Convert_objects: 'M': bad vnum %d.", pReset->arg1);
+						bugf("Convert_objects: 'M': bad vnum %ld.",
+							 pReset->arg1);
 					break;
 
 				case 'O':
 					if (!(pObj = get_obj_index(pReset->arg1)))
 					{
-						bug("Convert_objects: 'O': bad vnum %d.", pReset->arg1);
+						bugf("Convert_objects: 'O': bad vnum %ld.",
+							 pReset->arg1);
 						break;
 					}
 
@@ -543,7 +523,7 @@
 
 					if (!pMob)
 					{
-						bug("Convert_objects: 'O': No mob reset yet.", 0);
+						bug("Convert_objects: 'O': No mob reset yet.");
 						break;
 					}
 
@@ -559,8 +539,8 @@
 
 						if (!(ppObj = get_obj_index(pReset->arg1)))
 						{
-							bug("Convert_objects: 'P': bad vnum %d.",
-								pReset->arg1);
+							bugf("Convert_objects: 'P': bad vnum %ld.",
+								 pReset->arg1);
 							break;
 						}
 
@@ -569,8 +549,8 @@
 
 						if (!(pObjTo = get_obj_index(pReset->arg3)))
 						{
-							bug("Convert_objects: 'P': bad vnum %d.",
-								pReset->arg3);
+							bugf("Convert_objects: 'P': bad vnum %ld.",
+								 pReset->arg3);
 							break;
 						}
 
@@ -585,16 +565,16 @@
 				case 'E':
 					if (!(pObj = get_obj_index(pReset->arg1)))
 					{
-						bug("Convert_objects: 'E' or 'G': bad vnum %d.",
-							pReset->arg1);
+						bugf("Convert_objects: 'E' or 'G': bad vnum %ld.",
+							 pReset->arg1);
 						break;
 					}
 
 					if (!pMob)
 					{
-						bug
-							("Convert_objects: 'E' or 'G': null mob for vnum %d.",
-							pReset->arg1);
+						bugf
+							("Convert_objects: 'E' or 'G': null mob for vnum %ld.",
+							 pReset->arg1);
 						break;
 					}
 
@@ -670,7 +650,7 @@
 	switch (pObjIndex->item_type)
 	{
 	default:
-		bug("Obj_convert: vnum %d bad type.", pObjIndex->item_type);
+		bugf("Obj_convert: type %d bad type.", pObjIndex->item_type);
 		break;
 
 	case ITEM_LIGHT:
@@ -954,15 +934,9 @@
 CH_CMD(do_memory_heap)
 {
 	chprint(ch, separator);
-#if (STRHASH==1)
-	rptsd("String Space allocated at DB boot", MAX_STRING / 1024);
-	rptdsd(nAllocString, "Strings in string space", sAllocString / 1024);
-	rptsd("Excess string space", MAX_STRING / 1024 - sAllocString / 1024);
-#elif (STRHASH==2)
-	chprintlnf(ch, " Strings %d (%d allocated)", str_count, str_real_count);
-#endif
 	chprintlnf(ch, " Perms %d blocks of %ld kb.",
 			   nAllocPerm, sAllocPerm / 1024);
+	chprintlnf(ch, " %d strings of %d kb.", nAllocString, sAllocString / 1024);
 
 	chprint(ch, separator);
 }
@@ -995,6 +969,9 @@
 CH_CMD(do_memory_stats)
 {
 	chprintlnf(ch, " HostName = %s.", HOSTNAME);
+	chprintlnf(ch, " UserName = %s.", UNAME);
+	chprintlnf(ch, " Running = %s.", EXE_FILE);
+	chprintlnf(ch, " From = %s.", CWDIR);
 	chprintlnf(ch, " Port = %d.", port);
 #if !defined(NO_WEB)
 	if (WebUP)
@@ -1003,7 +980,6 @@
 #if !defined(WIN32)
 	chprintlnf(ch, " Current process ID is %d.", getpid());
 #endif
-	chprintlnf(ch, " Log All = %s.", fLogAll ? "TRUE" : "FALSE");
 }
 
 CH_CMD(do_memory)
@@ -1050,106 +1026,6 @@
 		(*iFun) (ch, argument);
 }
 
-void strspace_alloc()
-{
-#if (STRHASH==1)
-	extern char *top_string;
-
-	if ((string_space = (char *) calloc(1, MAX_STRING)) == NULL)
-	{
-		logf("Unable to allocate %d kB string space from system.",
-			 MAX_STRING / 1024);
-		exit(1);
-	}
-	top_string = string_space;
-#endif
-}
-
-/* Function Name: FILE *file_open (const char *mode, char *fmt,...)
-
- * this function closes fpReserve (if open), and opens a stream to the
- * file specified, with the specified modes.
- */
-FILE *file_open(const char *file, const char *mode)
-{
-	FILE *fp = NULL;
-
-/* fpReserve open? */
-	if (fpReserve != NULL)
-	{
-		/* Assuming that fpReserve *will* get re-opened sometime */
-		fclose(fpReserve);
-		fpReserve = NULL;
-	}
-
-/* Open the new stream */
-	fp = fopen(file, mode);
-
-	return fp;
-}
-
-/* Function Name: bool file_close (FILE *fp)
-
- * this function closes the stream specified, and attempts to re-open
- * fpReserve, if it's not already open.
- */
-bool file_close(FILE * fp)
-{
-	if (fp != NULL)
-		fclose(fp);
-
-/* fpReserve already open? */
-	if (fpReserve == NULL)
-		/* Nope, let's open */
-		fpReserve = fopen(NULL_FILE, "r");
-
-	return TRUE;
-}
-
-FILE_DATA *fopen_temp(const char *file)
-{
-	FILE_DATA *fp;
-	char temp[PATH_MAX];
-
-	if (IS_NULLSTR(file))
-		return NULL;
-
-	alloc_mem(fp, FILE_DATA, 1);
-
-	if (!fp)
-		return NULL;
-
-	strncpy(fp->name, file, PATH_MAX);
-#if !defined(WIN32) && !defined(__CYGWIN__)
-	snprintf(temp, PATH_MAX, "%s.tmp%d", file, number_percent());
-#else
-	strncpy(temp, file, PATH_MAX);
-#endif
-	strncpy(fp->tmp_name, temp, PATH_MAX);
-	if ((fp->file = file_open(fp->tmp_name, "w")) == NULL)
-	{
-		file_close(fp->file);
-		free_mem(fp);
-		fp = NULL;
-		return NULL;
-	}
-	return fp;
-}
-
-void fclose_temp(FILE_DATA * fp)
-{
-	if (fp)
-	{
-		file_close(fp->file);
-#if !defined(WIN32) && !defined(__CYGWIN__)
-		if (str_cmp(fp->tmp_name, fp->name))
-			rename(fp->tmp_name, fp->name);
-#endif
-		free_mem(fp);
-	}
-	fp = NULL;
-}
-
 const struct dofun_type dofun_table[] = {
 #define MAKE_COMMAND_TABLE
 #include "dofun.h"
@@ -1176,7 +1052,7 @@
 		if (!str_cmp(name, dofun_table[i].name))
 			return dofun_table[i].fun;
 
-	if (fBootDb)
+	if (run_level == RUNLEVEL_BOOTING)
 		bugf("Unknown command %s", name);
 
 	return &do_null;
@@ -1254,25 +1130,13 @@
 	return;
 }
 
-void load_bank_data(void)
-{
-	FILE *fp;
-	extern int share_value;
-
-	if ((fp = file_open(BANK_FILE, "r")) != NULL)
-	{
-		share_value = fread_number(fp);
-	}
-	file_close(fp);
-}
-
-void load_objprogs(FILE * fp)
+void load_objprogs(READ_DATA * fp)
 {
 	PROG_CODE *pOprog;
 
 	if (current_area == NULL)
 	{
-		bug("Load_objprogs: no #AREA seen yet.", 0);
+		bug("Load_objprogs: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -1281,42 +1145,42 @@
 		vnum_t vnum;
 		char letter;
 
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		if (letter != '#')
 		{
-			bug("Load_objprogs: # not found.", 0);
+			bug("Load_objprogs: # not found.");
 			exit(1);
 		}
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (vnum == 0)
 			break;
 
-		fBootDb = FALSE;
+		run_level = RUNLEVEL_BOOT_NOEXIT;
 		if (get_prog_index(vnum, PRG_OPROG) != NULL)
 		{
-			bug("Load_objprogs: vnum %d duplicated.", vnum);
+			bugf("Load_objprogs: vnum %ld duplicated.", vnum);
 			exit(1);
 		}
-		fBootDb = TRUE;
+		run_level = RUNLEVEL_BOOTING;
 
 		pOprog = new_pcode();
 		pOprog->vnum = vnum;
-		free_string(pOprog->code);
-		pOprog->code = fread_string(fp);
+		free_read_string(pOprog->code, fp);
+		pOprog->area = current_area;
 		LINK(pOprog, oprog_first, oprog_last, next, prev);
 		top_oprog_index++;
 	}
 	return;
 }
 
-void load_roomprogs(FILE * fp)
+void load_roomprogs(READ_DATA * fp)
 {
 	PROG_CODE *pRprog;
 
 	if (current_area == NULL)
 	{
-		bug("Load_roomprogs: no #AREA seen yet.", 0);
+		bug("Load_roomprogs: no #AREA seen yet.");
 		exit(1);
 	}
 
@@ -1325,29 +1189,29 @@
 		vnum_t vnum;
 		char letter;
 
-		letter = fread_letter(fp);
+		letter = read_letter(fp);
 		if (letter != '#')
 		{
-			bug("Load_roomprogs: # not found.", 0);
+			bug("Load_roomprogs: # not found.");
 			exit(1);
 		}
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (vnum == 0)
 			break;
 
-		fBootDb = FALSE;
+		run_level = RUNLEVEL_BOOT_NOEXIT;
 		if (get_prog_index(vnum, PRG_RPROG) != NULL)
 		{
 			bugf("Load_roomprogs: vnum %ld duplicated.", vnum);
 			exit(1);
 		}
-		fBootDb = TRUE;
+		run_level = RUNLEVEL_BOOTING;
 
 		pRprog = new_pcode();
 		pRprog->vnum = vnum;
-		free_string(pRprog->code);
-		pRprog->code = fread_string(fp);
+		free_read_string(pRprog->code, fp);
+		pRprog->area = current_area;
 		LINK(pRprog, rprog_first, rprog_last, next, prev);
 		top_rprog_index++;
 	}
@@ -1536,7 +1400,7 @@
 		iMemPerm = 0;
 		if ((pMemPerm = (char *) calloc(1, MAX_PERM_BLOCK)) == NULL)
 		{
-			perror("Alloc_perm");
+			log_error("Alloc_perm");
 			exit(1);
 		}
 	}
@@ -1555,19 +1419,19 @@
 
 	if (!command)
 	{
-		bug("add_command: NULL command", 0);
+		bug("add_command: NULL command");
 		return;
 	}
 
 	if (!command->name)
 	{
-		bug("add_command: NULL command->name", 0);
+		bug("add_command: NULL command->name");
 		return;
 	}
 
 	if (!command->do_fun)
 	{
-		bug("add_command: NULL command->do_fun", 0);
+		bug("add_command: NULL command->do_fun");
 		return;
 	}
 
@@ -1584,7 +1448,7 @@
 
 	if (!command)
 	{
-		bug("unlink_command: NULL command", 0);
+		bug("unlink_command: NULL command");
 		return;
 	}
 
@@ -1599,7 +1463,7 @@
 
 	if (!social)
 	{
-		bug("unlink_social: NULL social", 0);
+		bug("unlink_social: NULL social");
 		return;
 	}
 
@@ -1617,13 +1481,13 @@
 
 	if (!social)
 	{
-		bug("add_social: NULL social", 0);
+		bug("add_social: NULL social");
 		return;
 	}
 
 	if (!social->name)
 	{
-		bug("add_social: NULL social->name", 0);
+		bug("add_social: NULL social->name");
 		return;
 	}
 
@@ -1678,4 +1542,216 @@
 	replace_string(pArea->credits, builder);
 	pArea->min_level = convert_level(low);
 	pArea->max_level = convert_level(high);
+}
+
+int reset_door(RESET_DATA * pReset, bool fRandom)
+{
+	if (pReset && pReset->command == 'R')
+	{
+		if (pReset->arg2 > 0 && pReset->arg2 <= MAX_DIR)
+		{
+			return pReset->arg2 - 1;
+		}
+		else if (fRandom && pReset->arg4 > 0 && pReset->arg4 <= MAX_DIR)
+		{
+			return pReset->arg4 - 1;
+		}
+	}
+	return -1;
+}
+
+int open_exit(ROOM_INDEX_DATA * toRoom, ROOM_INDEX_DATA * pRoom,
+			  RESET_DATA * pReset)
+{
+	int door;
+
+	if ((door = reset_door(pReset, FALSE)) != -1)
+	{
+		if (toRoom->exit[rev_dir[door]] != NULL)
+			return -1;
+
+		return door;
+	}
+	for (door = 0; door < MAX_DIR; door++)
+	{
+		if (!toRoom->exit[rev_dir[door]] && !pRoom->exit[door])
+			return door;
+	}
+	return -1;
+}
+
+void clean_temp_exit(ROOM_INDEX_DATA * pRoom, int door)
+{
+	ROOM_INDEX_DATA *pToRoom;
+
+	if (!pRoom || (door < 0 && door >= MAX_DIR) ||
+		pRoom->exit[door] == NULL
+		|| !IS_SET(pRoom->exit[door]->exit_info, EX_TEMP))
+		return;
+
+	if ((pToRoom = pRoom->exit[door]->u1.to_room) != NULL)
+	{
+		int rev = rev_dir[door];
+
+		if (pToRoom->exit[rev]
+			&& IS_SET(pToRoom->exit[rev]->exit_info, EX_TEMP))
+		{
+			free_exit(pToRoom->exit[rev]);
+			pToRoom->exit[rev] = NULL;
+		}
+	}
+
+	free_exit(pRoom->exit[door]);
+	pRoom->exit[door] = NULL;
+}
+
+void clean_entrance(ROOM_INDEX_DATA * pRoom, RESET_DATA * pReset)
+{
+	int door;
+
+	if (!pRoom)
+		return;
+
+	if ((door = reset_door(pReset, TRUE)) != -1)
+	{
+		clean_temp_exit(pRoom, door);
+		return;
+	}
+	for (door = 0; door < MAX_DIR; door++)
+	{
+		clean_temp_exit(pRoom, door);
+	}
+}
+
+void add_random_exit(ROOM_INDEX_DATA * pRoom, RESET_DATA * pReset, bool Area)
+{
+	EXIT_DATA *pExit, *toExit;
+	ROOM_INDEX_DATA *toRoom;
+	int door, rev, safe = 0;
+	vnum_t minvn, maxvn;
+
+	if (!pRoom)
+		return;
+
+	if (Area)
+	{
+		minvn = pRoom->area->min_vnum;
+		maxvn = pRoom->area->max_vnum;
+	}
+	else
+	{
+		minvn = 2;
+		maxvn = top_vnum_room;
+	}
+
+	clean_entrance(pRoom, pReset);
+
+	for (;;)
+	{
+		toRoom = get_room_index(number_range(minvn, maxvn));
+		if (toRoom != NULL && !IS_SET(toRoom->room_flags, ROOM_PRIVATE)
+			&& !IS_SET(toRoom->room_flags, ROOM_SOLITARY)
+			&& !IS_SET(toRoom->room_flags, ROOM_ARENA)
+			&& !IS_SET(toRoom->room_flags, ROOM_BANK)
+			&& !IS_SET(toRoom->room_flags, ROOM_IMP_ONLY)
+			&& !IS_SET(toRoom->room_flags, ROOM_GODS_ONLY)
+			&& !IS_SET(toRoom->room_flags, ROOM_HEROES_ONLY)
+			&& !IS_SET(toRoom->room_flags, ROOM_NEWBIES_ONLY)
+			&& (Area
+				|| !IS_SET(toRoom->area->area_flags,
+						   AREA_CLOSED | AREA_PLAYER_HOMES))
+			&& IS_NULLSTR(toRoom->owner) && (Area || toRoom->clan == NULL)
+			&& (door = open_exit(toRoom, pRoom, pReset)) != -1)
+			break;
+		if (safe++ > top_room)
+			return;
+	}
+
+	pExit = new_exit();
+	pExit->u1.to_room = toRoom;
+	pExit->orig_door = door;
+	SET_BIT(pExit->rs_flags, EX_TEMP);
+	SET_BIT(pExit->exit_info, EX_TEMP);
+	pRoom->exit[door] = pExit;
+
+	rev = rev_dir[door];
+	toExit = new_exit();
+	toExit->u1.to_room = pRoom;
+	toExit->orig_door = rev;
+	SET_BIT(toExit->rs_flags, EX_TEMP);
+	SET_BIT(toExit->exit_info, EX_TEMP);
+	toRoom->exit[rev] = toExit;
+
+	// arg4 doesn't save so we can use it to keep track
+	// of random exit doors
+	if (pReset && pReset->arg4 != -1)
+		pReset->arg4 = door + 1;
+}
+
+bool check_directories(void)
+{
+	bool problem = FALSE;
+	int i;
+
+	for (i = 0; directories_table[i].directory != NULL; i++)
+	{
+		if (chdir(directories_table[i].directory))
+		{
+			if (strlen(directories_table[i].directory) > 0)
+			{
+				logf("no directory %-16s - used for '%s'",
+					 directories_table[i].directory, directories_table[i].text);
+				problem = TRUE;
+			}
+		}
+		if (chdir(CWDIR))
+		{
+			logf("UNABLE TO CHANGE BACK TO THE DEFAULT DIRECTORY!!!\n%s",
+				 CWDIR);
+			problem = TRUE;
+		}
+	}
+
+	if (!problem)
+		return problem;
+
+	for (i = 0; directories_table[i].directory != NULL; i++)
+	{
+		if (chdir(directories_table[i].directory))
+		{
+			if (strlen(directories_table[i].directory) > 0)
+			{
+				char dbuf[MIL];
+				sprintf(dbuf, "mkdir %s", directories_table[i].directory);
+
+				logf("creating dir %-15s - used for '%s'",
+					 directories_table[i].directory, directories_table[i].text);
+
+				if (system(dbuf))
+				{
+					logf("could not create dir %-8s  - used for '%s'",
+						 directories_table[i].directory,
+						 directories_table[i].text);
+					problem = TRUE;
+				}
+				else
+					problem = FALSE;
+			}
+		}
+		if (chdir(CWDIR))
+		{
+			log_string("UNABLE TO CHANGE BACK TO THE DEFAULT DIRECTORY!!!");
+			log_string(CWDIR);
+			problem = TRUE;
+		}
+	}
+
+	if (problem)
+	{
+		logf
+			("The code couldn't create the above directory/directories for you..."
+			 "see if you can fix the problem manually.");
+	}
+
+	return problem;
 }
Only in new: defines.h
diff -ur -x config -x o -x rom src/dofun.h new/dofun.h
--- src/dofun.h	Tue May 27 02:46:36 2003
+++ new/dofun.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 #if defined(COMMAND_FUN)
@@ -153,7 +153,6 @@
 COMMAND_FUN (do_password)
 COMMAND_FUN (do_peace)
 COMMAND_FUN (do_pecho)
-COMMAND_FUN (do_permban)
 COMMAND_FUN (do_pick)
 COMMAND_FUN (do_play)
 COMMAND_FUN (do_pmote)
@@ -192,7 +191,7 @@
 COMMAND_FUN (do_say)
 COMMAND_FUN (do_scan)
 COMMAND_FUN (do_score)
-COMMAND_FUN (do_scroll)
+COMMAND_FUN (do_screen)
 COMMAND_FUN (do_sell)
 COMMAND_FUN (do_set)
 COMMAND_FUN (do_shout)
@@ -216,7 +215,6 @@
 COMMAND_FUN (do_stat)
 COMMAND_FUN (do_steal)
 COMMAND_FUN (do_story)
-COMMAND_FUN (do_string)
 COMMAND_FUN (do_surrender)
 COMMAND_FUN (do_switch)
 COMMAND_FUN (do_tell)
@@ -262,6 +260,7 @@
 COMMAND_FUN (do_hedit)
 COMMAND_FUN (do_colour)
 COMMAND_FUN (do_colourset)
+COMMAND_FUN (do_copyove)
 COMMAND_FUN (do_copyover)
 COMMAND_FUN (do_sedit)
 COMMAND_FUN (do_disable)
@@ -326,5 +325,17 @@
 COMMAND_FUN (do_map)
 COMMAND_FUN (do_timezone)
 COMMAND_FUN (do_crash)
+COMMAND_FUN (do_chanedit)
+COMMAND_FUN (do_mudedit)
+COMMAND_FUN (do_songedit)
+COMMAND_FUN (do_mxp)
+COMMAND_FUN (do_portal)
+COMMAND_FUN (do_imp)
+COMMAND_FUN (do_pueblo)
+COMMAND_FUN (do_msp)
+COMMAND_FUN (do_sskill)
+COMMAND_FUN (do_stance)
+COMMAND_FUN (do_autostance)
+COMMAND_FUN (do_ignore)
 
 // *INDENT-ON*
diff -ur -x config -x o -x rom src/economy.c new/economy.c
--- src/economy.c	Tue May 27 02:46:35 2003
+++ new/economy.c	Sun Aug 31 19:23:20 2003
@@ -22,16 +22,11 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <stdio.h>
-#include <time.h>
 #include "merc.h"
 
-int share_value;
-
 #define MAX_IN_BANK 20000000
 
 CH_CMD(do_balance)
@@ -41,7 +36,7 @@
 			   "Shares  : %d gold in %d shares\n\r", ch->pcdata->gold_bank,
 			   ch->pcdata->silver_bank,
 			   ch->gold, ch->silver,
-			   (ch->pcdata->shares * share_value), ch->pcdata->shares);
+			   (ch->pcdata->shares * mud_info.share_value), ch->pcdata->shares);
 }
 
 CH_CMD(do_bank)
@@ -282,11 +277,11 @@
 				chprintln(ch, "The Mayor has set a limit of 10000 shares.");
 				return;
 			}
-			if ((amount * share_value) > ch->pcdata->gold_bank)
+			if ((amount * mud_info.share_value) > ch->pcdata->gold_bank)
 			{
 				chprintlnf(ch,
 						   "%d shares will cost you %d gold, deposit more gold.",
-						   amount, (amount * share_value));
+						   amount, (amount * mud_info.share_value));
 				return;
 			}
 			if (amount < 0)
@@ -296,11 +291,13 @@
 				return;
 			}
 			ch->pcdata->gold_bank =
-				UMAX(0, ch->pcdata->gold_bank - (amount * share_value));
+				UMAX(0,
+					 ch->pcdata->gold_bank - (amount * mud_info.share_value));
 			ch->pcdata->shares = URANGE(0, ch->pcdata->shares + amount, 10000);
 			chprintlnf(ch,
 					   "You buy %d shares for %d gold, you now have %d shares.",
-					   amount, (amount * share_value), ch->pcdata->shares);
+					   amount, (amount * mud_info.share_value),
+					   ch->pcdata->shares);
 			return;
 		}
 	}
@@ -324,28 +321,32 @@
 				return;
 			}
 
-			if (ch->pcdata->gold_bank + (amount * share_value) >= MAX_IN_BANK)
+			if (ch->pcdata->gold_bank + (amount * mud_info.share_value) >=
+				MAX_IN_BANK)
 				ch->pcdata->gold_bank = MAX_IN_BANK;
 			else
 				ch->pcdata->gold_bank =
-					UMAX(0, ch->pcdata->gold_bank + (amount * share_value));
+					UMAX(0,
+						 ch->pcdata->gold_bank +
+						 (amount * mud_info.share_value));
 			ch->pcdata->shares = UMAX(0, ch->pcdata->shares - amount);
 			chprintlnf(ch,
 					   "You sell %d shares for %d gold, you now have %d shares.",
-					   amount, (amount * share_value), ch->pcdata->shares);
+					   amount, (amount * mud_info.share_value),
+					   ch->pcdata->shares);
 			return;
 		}
 	}
 
 	if (!str_prefix(arg1, "check"))
 	{
-		chprintlnf(ch, "The current shareprice is %d.", share_value);
+		chprintlnf(ch, "The current shareprice is %d.", mud_info.share_value);
 		if (ch->pcdata->shares)
 		{
 			chprintlnf(ch,
 					   "You currently have %d shares, (%d a share) worth totally %d gold.",
-					   ch->pcdata->shares, share_value, (ch->pcdata->shares *
-														 share_value));
+					   ch->pcdata->shares, mud_info.share_value,
+					   (ch->pcdata->shares * mud_info.share_value));
 		}
 		return;
 	}
diff -ur -x config -x o -x rom src/effects.c new/effects.c
--- src/effects.c	Tue May 27 02:46:35 2003
+++ new/effects.c	Sun Aug 31 19:23:20 2003
@@ -22,15 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "recycle.h"
 
diff -ur -x config -x o -x rom src/explored.c new/explored.c
--- src/explored.c	Tue May 27 02:46:35 2003
+++ new/explored.c	Sun Aug 31 19:23:20 2003
@@ -22,18 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
 #include "merc.h"
 
 int bitcount(char c)
@@ -141,7 +132,7 @@
 	int bit = 0;
 	int count = 0;
 
-	fprintf(fp, "RoomRLE      %d", bit);
+	fprintf(fp, "RoomRLE\t\t%d", bit);
 
 	for (pIndex = 0; pIndex < MAX_VNUM; pIndex++)
 	{
@@ -188,6 +179,42 @@
 		}
 		while (pIndex < pos + count);
 		pos = pIndex;
+		bit = (bit == 1) ? 0 : 1;
+	}
+	return;
+}
+
+void read_rle(char *explored, READ_DATA * str)
+{
+	vnum_t index;
+	int bit = 0;
+	int count = 0;
+	vnum_t pos = 0;
+
+	index = 0;
+
+	bit = read_number(str);
+
+	for (;;)
+	{
+		count = read_number(str);
+
+		if (count < 0)
+			break;
+		if (count == 0)
+			continue;
+
+		do
+		{
+			if (bit == 1)
+			{
+				STR_SET_BIT(explored, index);
+			}
+			index++;
+		}
+		while (index < pos + count);
+
+		pos = index;
 		bit = (bit == 1) ? 0 : 1;
 	}
 	return;
diff -ur -x config -x o -x rom src/fight.c new/fight.c
--- src/fight.c	Tue May 27 02:46:36 2003
+++ new/fight.c	Sun Aug 31 19:23:20 2003
@@ -22,35 +22,30 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 
 /*
  * Local functions.
  */
-void check_assist args((CHAR_DATA * ch, CHAR_DATA * victim));
-bool check_dodge args((CHAR_DATA * ch, CHAR_DATA * victim));
-bool check_parry args((CHAR_DATA * ch, CHAR_DATA * victim));
-bool check_shield_block args((CHAR_DATA * ch, CHAR_DATA * victim));
-void dam_message
-args((CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, bool immune));
-void death_cry args((CHAR_DATA * ch));
-void group_gain args((CHAR_DATA * ch, CHAR_DATA * victim));
-int xp_compute args((CHAR_DATA * gch, CHAR_DATA * victim, int total_levels));
-void make_corpse args((CHAR_DATA * ch));
-void one_hit args((CHAR_DATA * ch, CHAR_DATA * victim, int dt, bool secondary));
-void mob_hit args((CHAR_DATA * ch, CHAR_DATA * victim, int dt));
-void raw_kill args((CHAR_DATA * victim));
-void set_fighting args((CHAR_DATA * ch, CHAR_DATA * victim));
-void disarm args((CHAR_DATA * ch, CHAR_DATA * victim));
+PROTOTYPE(void check_assist, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool check_dodge, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool check_parry, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool check_shield_block, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void dam_message, (CHAR_DATA *, CHAR_DATA *, int, int, bool));
+PROTOTYPE(void death_cry, (CHAR_DATA *));
+PROTOTYPE(void group_gain, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(int xp_compute, (CHAR_DATA *, CHAR_DATA *, int));
+PROTOTYPE(void make_corpse, (CHAR_DATA *));
+PROTOTYPE(void one_hit, (CHAR_DATA *, CHAR_DATA *, int, bool));
+PROTOTYPE(void mob_hit, (CHAR_DATA *, CHAR_DATA *, int));
+PROTOTYPE(void raw_kill, (CHAR_DATA *));
+PROTOTYPE(void set_fighting, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void disarm, (CHAR_DATA *, CHAR_DATA *));
 
 /*
  * Control the fights going on.
@@ -209,6 +204,138 @@
 	}
 }
 
+void special_move(CHAR_DATA * ch, CHAR_DATA * victim)
+{
+	if (!victim || victim->position == POS_DEAD)
+		return;
+
+	switch (number_range(1, 7))
+	{
+	default:
+		return;
+	case 1:
+		act
+			("{RYou pull your hands into your waist then snap them into $N's{R stomach.{x",
+			 ch, NULL, victim, TO_CHAR);
+		act
+			("{R$n{R pulls $s{R hands into $s{R waist then snaps them into your stomach.{x",
+			 ch, NULL, victim, TO_VICT);
+		act
+			("{R$n{R pulls $s{R hands into $s{R waist then snaps them into $N's{R stomach.{x",
+			 ch, NULL, victim, TO_NOTVICT);
+		act
+			("{RYou double over in agony, and fall to the ground gasping for breath.{x",
+			 victim, NULL, NULL, TO_CHAR);
+		act
+			("{R$n{R doubles over in agony, and falls to the ground gasping for breath.{x",
+			 victim, NULL, NULL, TO_ROOM);
+		break;
+	case 2:
+		act("{RYou spin in a low circle, catching $N{R behind $S{R ankle.{x",
+			ch, NULL, victim, TO_CHAR);
+		act("{R$n{R spins in a low circle, catching you behind your ankle.{x",
+			ch, NULL, victim, TO_VICT);
+		act("{R$n{R spins in a low circle, catching $N{R behind $S{R ankle.{x",
+			ch, NULL, victim, TO_NOTVICT);
+		act("{RYou crash to the ground, stunned.{x", victim, NULL, NULL,
+			TO_CHAR);
+		act("{R$n{R crashes to the ground, stunned.{x", victim, NULL, NULL,
+			TO_ROOM);
+		break;
+	case 3:
+		act("{RYou roll between $N's{R legs and flip to your feet.{x", ch,
+			NULL, victim, TO_CHAR);
+		act("{R$n{R rolls between your legs and flips to $s{R feet.{x", ch,
+			NULL, victim, TO_VICT);
+		act("{R$n{R rolls between $N's{R legs and flips to $s{R feet.{x", ch,
+			NULL, victim, TO_NOTVICT);
+		act
+			("{RYou spin around and smash your elbow into the back of $N's{R head.{x",
+			 ch, NULL, victim, TO_CHAR);
+		act
+			("{R$n{R spins around and smashes $s{R elbow into the back of your head.{x",
+			 ch, NULL, victim, TO_VICT);
+		act
+			("{R$n{R spins around and smashes $s{R elbow into the back of $N's{R head.{x",
+			 ch, NULL, victim, TO_NOTVICT);
+		act("{RYou fall to the ground, stunned.{x", victim, NULL, NULL,
+			TO_CHAR);
+		act("{R$n{R falls to the ground, stunned.{x", victim, NULL, NULL,
+			TO_ROOM);
+		break;
+	case 4:
+		act
+			("{RYou somersault over $N's{R head and land lightly on your toes.{x",
+			ch, NULL, victim, TO_CHAR);
+		act("{R$n{R somersaults over your head and lands lightly on $s toes.{x",
+			ch, NULL, victim, TO_VICT);
+		act
+			("{R$n{R somersaults over $N's{R head and lands lightly on $s toes.{x",
+			 ch, NULL, victim, TO_NOTVICT);
+		act
+			("{RYou roll back onto your shoulders and kick both feet into $N's{R back.{x",
+			 ch, NULL, victim, TO_CHAR);
+		act
+			("{R$n{R rolls back onto $s{R shoulders and kicks both feet into your back.{x",
+			 ch, NULL, victim, TO_VICT);
+		act
+			("{R$n{R rolls back onto $s{R shoulders and kicks both feet into $N's{R back.{x",
+			 ch, NULL, victim, TO_NOTVICT);
+		act("{RYou fall to the ground, stunned.", victim, NULL, NULL, TO_CHAR);
+		act("{R$n{R falls to the ground, stunned.", victim, NULL, NULL,
+			TO_ROOM);
+		act("{RYou flip back up to your feet.", ch, NULL, NULL, TO_CHAR);
+		act("{R$n{R flips back up to $s feet.", ch, NULL, NULL, TO_ROOM);
+		break;
+	case 5:
+		act("{RYou grab $N{R by the waist and hoist $M{R above your head.{x",
+			ch, NULL, victim, TO_CHAR);
+		act("{R$n{R grabs $N{R by the waist and hoists $M{R above $s{R head.{x",
+			ch, NULL, victim, TO_NOTVICT);
+		act("{R$n{R grabs you by the waist and hoists you above $s{R head.{x",
+			ch, NULL, victim, TO_VICT);
+		act("{RYou crash to the ground, stunned.{x", victim, NULL, NULL,
+			TO_CHAR);
+		act("{R$n{R crashes to the ground, stunned.{x", victim, NULL, NULL,
+			TO_ROOM);
+		break;
+	case 6:
+		act("{RYou grab $N{R by the head and slam $S{R face into your knee.{x",
+			ch, NULL, victim, TO_CHAR);
+		act
+			("{R$n{R grabs you by the head and slams your face into $s{R knee.{x",
+			ch, NULL, victim, TO_VICT);
+		act
+			("{R$n{R grabs $N{R by the head and slams $S{R face into $s{R knee.{x",
+			 ch, NULL, victim, TO_NOTVICT);
+		act("{RYou crash to the ground, stunned.{x", victim, NULL, NULL,
+			TO_CHAR);
+		act("{R$n{R crashes to the ground, stunned.{x", victim, NULL, NULL,
+			TO_ROOM);
+		act("{RYou flip back up to your feet.{x", ch, NULL, NULL, TO_CHAR);
+		act("{R$n{R flips back up to $s{R feet.{x", ch, NULL, NULL, TO_ROOM);
+		break;
+	case 7:
+		act
+			("{RYou duck under $N's{R attack and pound your fist into $S{R stomach.{x",
+			 ch, NULL, victim, TO_CHAR);
+		act
+			("{R$n{R ducks under your attack and pounds $s{R fist into your stomach.{x",
+			 ch, NULL, victim, TO_VICT);
+		act
+			("{R$n{R ducks under $N's{R attack and pounds $s{R fist into $N's{R stomach.{x",
+			 ch, NULL, victim, TO_NOTVICT);
+		act("{RYou double over in agony.{x", victim, NULL, NULL, TO_CHAR);
+		act("{R$n{R doubles over in agony.{x", victim, NULL, NULL, TO_ROOM);
+		break;
+	}
+
+	stop_fighting(victim, TRUE);
+	victim->position = POS_STUNNED;
+
+	return;
+}
+
 /*
  * Do one group of attacks.
  */
@@ -251,6 +378,13 @@
 	if (ch->fighting != victim || dt == gsn_backstab)
 		return;
 
+	if (IS_VALID_STANCE(GET_STANCE(ch, STANCE_CURRENT))
+		&& GET_STANCE(ch, STANCE_CURRENT) >= 200 && number_percent() == 50)
+	{
+		special_move(ch, victim);
+		return;
+	}
+
 	chance = get_skill(ch, gsn_second_attack) / 2;
 
 	if (IS_AFFECTED(ch, AFF_SLOW))
@@ -267,7 +401,7 @@
 	chance = get_skill(ch, gsn_third_attack) / 4;
 
 	if (IS_AFFECTED(ch, AFF_SLOW))
-		chance = 0;;
+		chance = 0;
 
 	if (number_percent() < chance)
 	{
@@ -277,6 +411,28 @@
 			return;
 	}
 
+	if (IS_STANCE(ch, STANCE_VIPER)
+		&& number_percent() < GET_STANCE(ch, STANCE_VIPER) * 0.5)
+	{
+		one_hit(ch, victim, dt, FALSE);
+		if (ch->fighting != victim)
+			return;
+	}
+	else if (IS_STANCE(ch, STANCE_MANTIS)
+			 && number_percent() < GET_STANCE(ch, STANCE_MANTIS) * 0.5)
+	{
+		one_hit(ch, victim, dt, FALSE);
+		if (ch->fighting != victim)
+			return;
+	}
+	else if (IS_STANCE(ch, STANCE_TIGER)
+			 && number_percent() < GET_STANCE(ch, STANCE_TIGER) * 0.5)
+	{
+		one_hit(ch, victim, dt, FALSE);
+		if (ch->fighting != victim)
+			return;
+	}
+
 	return;
 }
 
@@ -544,6 +700,7 @@
 	{
 		/* Miss. */
 		damage(ch, victim, 0, dt, dam_type, TRUE);
+		improve_stance(ch);
 		tail_chain();
 		return;
 	}
@@ -596,6 +753,17 @@
 	/*
 	 * Bonuses.
 	 */
+
+	if (IS_STANCE(ch, STANCE_NORMAL))
+	{
+		if (IS_NPC(ch))
+			dam = dam * 113 / 100;
+		else
+			dam = dam * 115 / 100;
+	}
+	else
+		dam = dambonus(ch, victim, dam, GET_STANCE(ch, STANCE_CURRENT));
+
 	if (get_skill(ch, gsn_enhanced_damage) > 0)
 	{
 		diceroll = number_percent();
@@ -731,7 +899,7 @@
 	 */
 	if (dam > 1200 && dt >= TYPE_HIT)
 	{
-		bug("Damage: %d: more than 1200 points!", dam);
+		bugf("Damage: %d: more than 1200 points!", dam);
 		dam = 1200;
 		if (!IS_IMMORTAL(ch))
 		{
@@ -820,9 +988,25 @@
 	 */
 	if (dt >= TYPE_HIT && ch != victim)
 	{
+		if (check_dodge(ch, victim))
+			return FALSE;
+		if (IS_STANCE(victim, STANCE_MONGOOSE)
+			&& GET_STANCE(victim, STANCE_MONGOOSE) > 100 && !can_counter(ch)
+			&& !can_bypass(ch, victim) && check_dodge(ch, victim))
+			return FALSE;
+		else if (IS_STANCE(victim, STANCE_SWALLOW)
+				 && GET_STANCE(victim, STANCE_SWALLOW) > 100 && !can_counter(ch)
+				 && !can_bypass(ch, victim) && check_dodge(ch, victim))
+			return FALSE;
 		if (check_parry(ch, victim))
 			return FALSE;
-		if (check_dodge(ch, victim))
+		if (IS_STANCE(victim, STANCE_CRANE)
+			&& GET_STANCE(victim, STANCE_CRANE) > 100 && !can_counter(ch)
+			&& !can_bypass(ch, victim) && check_parry(ch, victim))
+			return FALSE;
+		else if (IS_STANCE(victim, STANCE_MANTIS)
+				 && GET_STANCE(victim, STANCE_MANTIS) > 100 && !can_counter(ch)
+				 && !can_bypass(ch, victim) && check_parry(ch, victim))
 			return FALSE;
 		if (check_shield_block(ch, victim))
 			return FALSE;
@@ -970,15 +1154,15 @@
 							   victim->level - victim->exp) / 3) + 50);
 			}
 			if (IS_NPC(ch))
-				victim->pcdata->gamestat[MOB_DEATHS]++;
+				ADD_STAT(victim, MOB_DEATHS, 1);
 			else
 			{
-				victim->pcdata->gamestat[PK_DEATHS]++;
-				ch->pcdata->gamestat[PK_KILLS]++;
+				ADD_STAT(victim, PK_DEATHS, 1);
+				ADD_STAT(ch, PK_KILLS, 1);
 			}
 		}
 		else if (!IS_NPC(ch))
-			ch->pcdata->gamestat[MOB_KILLS]++;
+			ADD_STAT(ch, MOB_KILLS, 1);
 
 		sprintf(log_buf, "%s got toasted by %s at %s [room %ld]",
 				(IS_NPC(victim) ? victim->short_descr : victim->name),
@@ -1371,7 +1555,7 @@
 		{
 			sprintf(buf, "Check_killer: %s bad AFF_CHARM",
 					IS_NPC(ch) ? ch->short_descr : ch->name);
-			bug(buf, 0);
+			bug(buf);
 			affect_strip(ch, gsn_charm_person);
 			REMOVE_BIT(ch->affected_by, AFF_CHARM);
 			return;
@@ -1426,6 +1610,14 @@
 	if (!can_see(ch, victim))
 		chance /= 2;
 
+	if (IS_STANCE(victim, STANCE_CRANE) && GET_STANCE(victim, STANCE_CRANE) > 0
+		&& !can_counter(ch) && !can_bypass(ch, victim))
+		chance += (GET_STANCE(victim, STANCE_CRANE) * 25 / 100);
+	else if (IS_STANCE(victim, STANCE_MANTIS)
+			 && GET_STANCE(victim, STANCE_MANTIS) > 0 && !can_counter(ch)
+			 && !can_bypass(ch, victim))
+		chance += (GET_STANCE(victim, STANCE_MANTIS) * 25 / 100);
+
 	if (number_percent() >= chance + victim->level - ch->level)
 		return FALSE;
 
@@ -1474,6 +1666,15 @@
 	if (!can_see(victim, ch))
 		chance /= 2;
 
+	if (IS_STANCE(victim, STANCE_MONGOOSE)
+		&& GET_STANCE(victim, STANCE_MONGOOSE) > 0 && !can_counter(ch)
+		&& !can_bypass(ch, victim))
+		(chance += GET_STANCE(victim, STANCE_MONGOOSE) * 25 / 100);
+	if (IS_STANCE(victim, STANCE_SWALLOW)
+		&& GET_STANCE(victim, STANCE_SWALLOW) > 0 && !can_counter(ch)
+		&& !can_bypass(ch, victim))
+		(chance += GET_STANCE(victim, STANCE_SWALLOW) * 25 / 100);
+
 	if (number_percent() >= chance + victim->level - ch->level)
 		return FALSE;
 
@@ -1524,7 +1725,7 @@
 {
 	if (ch->fighting != NULL)
 	{
-		bug("Set_fighting: already fighting", 0);
+		bug("Set_fighting: already fighting");
 		return;
 	}
 
@@ -1533,6 +1734,7 @@
 
 	ch->fighting = victim;
 	ch->position = POS_FIGHTING;
+	autodrop(ch);
 
 	return;
 }
@@ -1551,9 +1753,9 @@
 			fch->fighting = NULL;
 			fch->position = IS_NPC(fch) ? fch->default_pos : POS_STANDING;
 			update_pos(fch);
+			SET_STANCE(fch, STANCE_CURRENT, STANCE_NONE);
 		}
 	}
-
 	return;
 }
 
@@ -1607,12 +1809,10 @@
 	corpse->level = ch->level;
 
 	sprintf(buf, corpse->short_descr, name);
-	free_string(corpse->short_descr);
-	corpse->short_descr = str_dup(buf);
+	replace_string(corpse->short_descr, buf);
 
 	sprintf(buf, corpse->description, name);
-	free_string(corpse->description);
-	corpse->description = str_dup(buf);
+	replace_string(corpse->description, buf);
 
 	for (obj = ch->first_carrying; obj != NULL; obj = obj_next)
 	{
@@ -1750,12 +1950,10 @@
 		obj->timer = number_range(4, 7);
 
 		sprintf(buf, obj->short_descr, name);
-		free_string(obj->short_descr);
-		obj->short_descr = str_dup(buf);
+		replace_string(obj->short_descr, buf);
 
 		sprintf(buf, obj->description, name);
-		free_string(obj->description);
-		obj->description = str_dup(buf);
+		replace_string(obj->description, buf);
 
 		if (obj->item_type == ITEM_FOOD)
 		{
@@ -1852,7 +2050,7 @@
 
 	if (members == 0)
 	{
-		bug("Group_gain: members.", members);
+		bug("Group_gain: members == 0.");
 		members = 1;
 		group_levels = ch->level;
 	}
@@ -2292,17 +2490,18 @@
 	{
 		if (ch == victim)
 		{
-			sprintf(buf1, "$n %s $melf%c$t", vp, punct);
-			sprintf(buf2, "You %s yourself%c%s", vs, punct,
-					SEE_DAMAGE(ch) ? chmesg : "");
+			sprintf(buf1, CTAG(_OHIT) "$n %s" CTAG(_OHIT) " $melf%c$t", vp,
+					punct);
+			sprintf(buf2, CTAG(_YHIT) "You %s" CTAG(_YHIT) " yourself%c%s", vs,
+					punct, SEE_DAMAGE(ch) ? chmesg : "{x");
 		}
 		else
 		{
-			sprintf(buf1, "$n %s $N%c$t", vp, punct);
-			sprintf(buf2, "You %s $N%c%s", vs, punct,
-					SEE_DAMAGE(ch) ? chmesg : "");
-			sprintf(buf3, "$n %s you%c%s", vp, punct,
-					SEE_DAMAGE(victim) ? vmesg : "");
+			sprintf(buf1, CTAG(_OHIT) "$n %s" CTAG(_OHIT) " $N%c$t", vp, punct);
+			sprintf(buf2, CTAG(_YHIT) "You %s" CTAG(_YHIT) " $N%c%s", vs, punct,
+					SEE_DAMAGE(ch) ? chmesg : "{x");
+			sprintf(buf3, CTAG(_VHIT) "$n %s" CTAG(_VHIT) " you%c%s", vp, punct,
+					SEE_DAMAGE(victim) ? vmesg : "{x");
 		}
 	}
 	else
@@ -2313,7 +2512,7 @@
 			attack = attack_table[dt - TYPE_HIT].noun;
 		else
 		{
-			bug("Dam_message: bad dt %d.", dt);
+			bugf("Dam_message: bad dt %d.", dt);
 			dt = TYPE_HIT;
 			attack = attack_table[0].name;
 		}
@@ -2322,31 +2521,37 @@
 		{
 			if (ch == victim)
 			{
-				sprintf(buf1, "$n is unaffected by $s own %s.", attack);
-				sprintf(buf2, "Luckily, you are immune to that.");
+				sprintf(buf1, CTAG(_OHIT) "$n is unaffected by $s own %s.{x",
+						attack);
+				sprintf(buf2, CTAG(_YHIT) "Luckily, you are immune to that.{x");
 			}
 			else
 			{
-				sprintf(buf1, "$N is unaffected by $n's %s!", attack);
-				sprintf(buf2, "$N is unaffected by your %s!", attack);
-				sprintf(buf3, "$n's %s is powerless against you.", attack);
+				sprintf(buf1, CTAG(_OHIT) "$N is unaffected by $n's %s!{x",
+						attack);
+				sprintf(buf2, CTAG(_YHIT) "$N is unaffected by your %s!{x",
+						attack);
+				sprintf(buf3, CTAG(_VHIT) "$n's %s is powerless against you.{x",
+						attack);
 			}
 		}
 		else
 		{
 			if (ch == victim)
 			{
-				sprintf(buf1, "$n's %s %s $m%c$t", attack, vp, punct);
-				sprintf(buf2, "Your %s %s you%c%s", attack, vp, punct,
-						SEE_DAMAGE(ch) ? chmesg : "");
+				sprintf(buf1, CTAG(_OHIT) "$n's %s %s" CTAG(_OHIT) " $m%c$t",
+						attack, vp, punct);
+				sprintf(buf2, CTAG(_YHIT) "Your %s %s" CTAG(_YHIT) " you%c%s",
+						attack, vp, punct, SEE_DAMAGE(ch) ? chmesg : "{x");
 			}
 			else
 			{
-				sprintf(buf1, "$n's %s %s $N%c$t", attack, vp, punct);
-				sprintf(buf2, "Your %s %s $N%c%s", attack, vp, punct,
-						SEE_DAMAGE(ch) ? chmesg : "");
-				sprintf(buf3, "$n's %s %s you%c%s", attack, vp, punct,
-						SEE_DAMAGE(victim) ? vmesg : "");
+				sprintf(buf1, CTAG(_OHIT) "$n's %s %s" CTAG(_OHIT) " $N%c$t",
+						attack, vp, punct);
+				sprintf(buf2, CTAG(_YHIT) "Your %s %s" CTAG(_YHIT) " $N%c%s",
+						attack, vp, punct, SEE_DAMAGE(ch) ? chmesg : "{x");
+				sprintf(buf3, CTAG(_VHIT) "$n's %s %s" CTAG(_VHIT) " you%c%s",
+						attack, vp, punct, SEE_DAMAGE(victim) ? vmesg : "{x");
 			}
 		}
 	}
@@ -2507,7 +2712,7 @@
 		return;
 	}
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		victim = ch->fighting;
 		if (victim == NULL)
@@ -2634,7 +2839,7 @@
 		return;
 	}
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		victim = ch->fighting;
 		if (victim == NULL)
@@ -2693,7 +2898,7 @@
 	/* level */
 	chance += (ch->level - victim->level) * 2;
 
-	/* sloppy hack to prevent false zeroes */
+	/* sloppy hack to prevent FALSE zeroes */
 	if (chance % 5 == 0)
 		chance += 1;
 
@@ -2729,6 +2934,8 @@
 	case (SECT_DESERT):
 		chance += 10;
 		break;
+	default:
+		break;
 	}
 
 	if (chance == 0)
@@ -2784,7 +2991,7 @@
 		return;
 	}
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		victim = ch->fighting;
 		if (victim == NULL)
@@ -2869,6 +3076,14 @@
 		victim->position = POS_RESTING;
 		damage(ch, victim, number_range(2, 2 + 2 * victim->size),
 			   gsn_trip, DAM_BASH, TRUE);
+		if (number_percent() < chance - 5
+			&& IS_VALID_STANCE(GET_STANCE(victim, STANCE_CURRENT)))
+		{
+			SET_STANCE(victim, STANCE_CURRENT, STANCE_NONE);
+			act("You trip up $N's stance!", ch, NULL, victim, TO_CHAR);
+			act("$n trips up $N's stance!", ch, NULL, victim, TO_NOTVICT);
+			act("$n trips up your stance!", ch, NULL, victim, TO_VICT);
+		}
 	}
 	else
 	{
@@ -2886,7 +3101,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Kill whom?");
 		return;
@@ -2956,7 +3171,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Murder whom?");
 		return;
@@ -3018,7 +3233,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Backstab whom?");
 		return;
@@ -3150,7 +3365,7 @@
 	CHAR_DATA *fch;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Rescue whom?");
 		return;
@@ -3358,7 +3573,7 @@
 	char arg[MAX_INPUT_LENGTH];
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Slay whom?");
 		return;
@@ -3387,4 +3602,454 @@
 	act("$n slays $N in cold blood!", ch, NULL, victim, TO_NOTVICT);
 	raw_kill(victim);
 	return;
+}
+
+CH_CMD(do_sskill)
+{
+	int ast = GET_STANCE(ch, STANCE_AUTODROP);
+
+	chprintlnf(ch, "{W%s", draw_line(ch, NULL, 0));
+	chprint(ch, stringf
+			(ch, 0, ALIGN_CENTER, NULL, "{G-==[ {RBasic Styles{G ]==-{x"));
+	chprintlnf(ch, "\n\r%s",
+			   stringf(ch, 0, ALIGN_CENTER, NULL,
+					   FORMATF
+					   ("Viper: {Y%-3d{x Crane: {Y%-3d{x Crab: {Y%-3d{x Mongoose: {Y%-3d{x Bull: {Y%-3d{x",
+						GET_STANCE(ch, STANCE_VIPER), GET_STANCE(ch,
+																 STANCE_CRANE),
+						GET_STANCE(ch, STANCE_CRAB), GET_STANCE(ch,
+																STANCE_MONGOOSE),
+						GET_STANCE(ch, STANCE_BULL))));
+	chprintlnf(ch, "{W%s", draw_line(ch, NULL, 0));
+	chprint(ch, stringf
+			(ch, 0, ALIGN_CENTER, NULL, "{G-==[ {RAdvanced Styles{G ]==-{x"));
+	chprintlnf(ch, "\n\r%s",
+			   stringf(ch, 0, ALIGN_CENTER, NULL,
+					   FORMATF
+					   ("Mantis: {Y%-3d{x Dragon: {Y%-3d{x Tiger: {Y%-3d{x Monkey: {Y%-3d{x Swallow: {Y%-3d{x",
+						GET_STANCE(ch, STANCE_MANTIS), GET_STANCE(ch,
+																  STANCE_DRAGON),
+						GET_STANCE(ch, STANCE_TIGER), GET_STANCE(ch,
+																 STANCE_MONKEY),
+						GET_STANCE(ch, STANCE_SWALLOW))));
+	chprintlnf(ch, "{W%s", draw_line(ch, NULL, 0));
+	chprintlnf(ch, "%s",
+			   stringf(ch, 0, ALIGN_CENTER, NULL,
+					   FORMATF("{RAutoStance: {x%s", get_stance_name(ast))));
+	return;
+}
+
+long dambonus(CHAR_DATA * ch, CHAR_DATA * victim, long dam, int stance)
+{
+	if (dam < 1)
+		return 0;
+
+	if (!IS_VALID_STANCE(stance))
+		return dam;
+
+	if (!can_counter(victim))
+	{
+		if (IS_STANCE(ch, STANCE_MONKEY))
+		{
+			int mindam = dam * 25 / 100;
+
+			dam *= (GET_STANCE(ch, STANCE_MONKEY) + 1) / 200;
+			if (dam < mindam)
+				dam = mindam;
+		}
+		else if (IS_STANCE(ch, STANCE_BULL)
+				 && GET_STANCE(ch, STANCE_BULL) > 100)
+			dam += dam * (GET_STANCE(ch, STANCE_BULL) / 100);
+		else if (IS_STANCE(ch, STANCE_DRAGON)
+				 && GET_STANCE(ch, STANCE_DRAGON) > 100)
+			dam += dam * (GET_STANCE(ch, STANCE_DRAGON) / 100);
+		else if (IS_STANCE(ch, STANCE_TIGER)
+				 && GET_STANCE(ch, STANCE_TIGER) > 100)
+			dam += dam * (GET_STANCE(ch, STANCE_TIGER) / 100);
+		else if (GET_STANCE(ch, STANCE_CURRENT) > 0
+				 && GET_STANCE(ch, stance) < 100)
+			dam = dam * 5 / 10;
+	}
+	if (!can_counter(ch))
+	{
+		if (IS_STANCE(victim, STANCE_CRAB)
+			&& GET_STANCE(victim, STANCE_CRAB) > 100)
+			dam /= GET_STANCE(victim, STANCE_CRAB) / 100;
+		else if (IS_STANCE(victim, STANCE_DRAGON)
+				 && GET_STANCE(victim, STANCE_DRAGON) > 100)
+			dam /= GET_STANCE(victim, STANCE_DRAGON) / 100;
+		else if (IS_STANCE(victim, STANCE_SWALLOW)
+				 && GET_STANCE(victim, STANCE_SWALLOW) > 100)
+			dam /= GET_STANCE(victim, STANCE_SWALLOW) / 100;
+	}
+	return dam;
+}
+
+bool can_counter(CHAR_DATA * ch)
+{
+	if (IS_STANCE(ch, STANCE_MONKEY))
+		return TRUE;
+
+	return FALSE;
+}
+
+bool can_bypass(CHAR_DATA * ch, CHAR_DATA * victim)
+{
+	if (IS_STANCE(ch, STANCE_VIPER))
+		return TRUE;
+
+	if (IS_STANCE(ch, STANCE_MANTIS))
+		return TRUE;
+
+	if (IS_STANCE(ch, STANCE_TIGER))
+		return TRUE;
+
+	return FALSE;
+}
+
+char *get_stance_name(int stance)
+{
+	static char stancename[2][100];
+	static int i;
+
+	i++;
+	i %= 2;
+
+	switch (stance)
+	{
+	case STANCE_VIPER:
+		sprintf(stancename[i], "viper");
+		break;
+	case STANCE_CRANE:
+		sprintf(stancename[i], "crane");
+		break;
+	case STANCE_CRAB:
+		sprintf(stancename[i], "crab");
+		break;
+	case STANCE_MONGOOSE:
+		sprintf(stancename[i], "mongoose");
+		break;
+	case STANCE_BULL:
+		sprintf(stancename[i], "bull");
+		break;
+	case STANCE_MANTIS:
+		sprintf(stancename[i], "mantis");
+		break;
+	case STANCE_DRAGON:
+		sprintf(stancename[i], "dragon");
+		break;
+	case STANCE_TIGER:
+		sprintf(stancename[i], "tiger");
+		break;
+	case STANCE_MONKEY:
+		sprintf(stancename[i], "monkey");
+		break;
+	case STANCE_SWALLOW:
+		sprintf(stancename[i], "swallow");
+		break;
+	default:
+		sprintf(stancename[i], "unknown");
+		break;
+	}
+	return (stancename[i]);
+}
+
+void improve_stance(CHAR_DATA * ch)
+{
+	char bufskill[25];
+	int dice1;
+	int dice2;
+	int stance;
+	int skill;
+
+	dice1 = number_percent();
+	dice2 = number_percent();
+
+	stance = GET_STANCE(ch, STANCE_CURRENT);
+	if (!IS_VALID_STANCE(stance))
+		return;
+	skill = GET_STANCE(ch, stance);
+	if (skill >= 200)
+	{
+		SET_STANCE(ch, stance, 200);
+		return;
+	}
+	if ((dice1 > skill && dice2 > skill) || (dice1 == 100 || dice2 == 100))
+		ch->stance[stance] += 1;
+	else
+		return;
+	if (skill == GET_STANCE(ch, stance))
+		return;
+
+	if (IS_NPC(ch))
+		return;
+
+	switch (GET_STANCE(ch, stance))
+	{
+
+	case 1:
+		sprintf(bufskill, "an apprentice of");
+		break;
+	case 26:
+		sprintf(bufskill, "a trainee of");
+		break;
+	case 51:
+		sprintf(bufskill, "a student of");
+		break;
+	case 76:
+		sprintf(bufskill, "fairly experienced in");
+		break;
+	case 101:
+		sprintf(bufskill, "well trained in");
+		break;
+	case 126:
+		sprintf(bufskill, "highly skilled in");
+		break;
+	case 151:
+		sprintf(bufskill, "an expert of");
+		break;
+	case 176:
+		sprintf(bufskill, "a master of");
+		break;
+	case 200:
+		sprintf(bufskill, "a grand master of");
+		break;
+	default:
+		return;
+	}
+
+	chprintlnf(ch, "{RYou are now %s the %s stance.{x", bufskill,
+			   get_stance_name(stance));
+	return;
+}
+
+CH_CMD(do_stance)
+{
+	char arg[MIL];
+	int selection;
+
+	argument = one_argument(argument, arg);
+
+	if (IS_NULLSTR(arg))
+	{
+		if (!IS_VALID_STANCE(GET_STANCE(ch, STANCE_CURRENT)))
+		{
+			SET_STANCE(ch, STANCE_CURRENT, STANCE_NORMAL);
+			chprintln(ch, "You drop into a fighting stance.");
+			act("$n drops into a fighting stance.", ch, NULL, NULL, TO_ROOM);
+		}
+		else
+		{
+			SET_STANCE(ch, STANCE_CURRENT, STANCE_NONE);
+			chprintln(ch, "You relax from your fighting stance.");
+			act("$n relaxes from $s fighting stance.", ch, NULL, NULL, TO_ROOM);
+		}
+		return;
+	}
+	if (IS_VALID_STANCE(GET_STANCE(ch, STANCE_CURRENT)))
+	{
+		chprintln
+			(ch,
+			 "You cannot change stances until you come up from the one you are currently in.");
+		return;
+	}
+	if (!str_cmp(arg, "none"))
+	{
+		selection = STANCE_NONE;
+		chprintln(ch, "You drop into a general fighting stance.");
+		act("$n drops into a general fighting stance.", ch, NULL, NULL,
+			TO_ROOM);
+	}
+	else if (!str_cmp(arg, "viper"))
+	{
+		selection = STANCE_VIPER;
+		chprintln(ch, "You arch your body into the viper fighting stance.");
+		act("$n arches $s body into the viper fighting stance.", ch, NULL,
+			NULL, TO_ROOM);
+	}
+	else if (!str_cmp(arg, "crane"))
+	{
+		selection = STANCE_CRANE;
+		chprintln(ch, "You swing your body into the crane fighting stance.");
+		act("$n swings $s body into the crane fighting stance.", ch, NULL,
+			NULL, TO_ROOM);
+	}
+	else if (!str_cmp(arg, "crab"))
+	{
+		selection = STANCE_CRAB;
+		chprintln(ch, "You squat down into the crab fighting stance.");
+		act("$n squats down into the crab fighting stance. ", ch, NULL, NULL,
+			TO_ROOM);
+	}
+	else if (!str_cmp(arg, "mongoose"))
+	{
+		selection = STANCE_MONGOOSE;
+		chprintln(ch, "You twist into the mongoose fighting stance.");
+		act("$n twists into the mongoose fighting stance. ", ch, NULL, NULL,
+			TO_ROOM);
+	}
+	else if (!str_cmp(arg, "bull"))
+	{
+		selection = STANCE_BULL;
+		chprintln(ch, "You hunch down into the bull fighting stance.");
+		act("$n hunches down into the bull fighting stance. ", ch, NULL,
+			NULL, TO_ROOM);
+	}
+	else
+	{
+		if (!str_cmp(arg, "mantis") && GET_STANCE(ch, STANCE_CRANE) >= 200
+			&& GET_STANCE(ch, STANCE_VIPER) >= 200)
+		{
+			selection = STANCE_MANTIS;
+			chprintln(ch,
+					  "You spin your body into the mantis fighting stance.");
+			act("$n spins $s body into the mantis fighting stance.", ch, NULL,
+				NULL, TO_ROOM);
+		}
+		else if (!str_cmp(arg, "dragon") && GET_STANCE(ch, STANCE_BULL) >= 200
+				 && GET_STANCE(ch, STANCE_CRAB) >= 200)
+		{
+			selection = STANCE_DRAGON;
+			chprintln(ch,
+					  "You coil your body into the dragon fighting stance.");
+			act("$n coils $s body into the dragon fighting stance.", ch, NULL,
+				NULL, TO_ROOM);
+		}
+		else if (!str_cmp(arg, "tiger") && GET_STANCE(ch, STANCE_BULL) >= 200
+				 && GET_STANCE(ch, STANCE_VIPER) >= 200)
+		{
+			selection = STANCE_TIGER;
+			chprintln(ch, "You lunge into the tiger fighting stance.");
+			act("$n lunges into the tiger fighting stance.", ch, NULL, NULL,
+				TO_ROOM);
+		}
+		else if (!str_cmp(arg, "monkey") && GET_STANCE(ch, STANCE_CRANE) >= 200
+				 && GET_STANCE(ch, STANCE_MONGOOSE) >= 200)
+		{
+			selection = STANCE_MONKEY;
+			chprintln
+				(ch, "You rotate your body into the monkey fighting stance.");
+			act("$n rotates $s body into the monkey fighting stance.", ch,
+				NULL, NULL, TO_ROOM);
+		}
+		else if (!str_cmp(arg, "swallow") && GET_STANCE(ch, STANCE_CRAB) >= 200
+				 && GET_STANCE(ch, STANCE_MONGOOSE) >= 200)
+		{
+			selection = STANCE_SWALLOW;
+			chprintln(ch, "You slide into the swallow fighting stance.");
+			act("$n slides into the swallow fighting stance.", ch, NULL,
+				NULL, TO_ROOM);
+		}
+		else
+		{
+			chprintln(ch, "Syntax is: stance <stance>.");
+			chprintln
+				(ch,
+				 "Stance being one of: None, Viper, Crane, Crab, Mongoose, Bull.");
+			chprintln(ch,
+					  "If all basic mastered Stance may be: Swallow, Mantis, Tiger, Dragon, Monkey.");
+			return;
+		}
+	}
+	SET_STANCE(ch, STANCE_CURRENT, selection);
+	if (IS_NPC(ch))
+		SET_STANCE(ch, selection, UMIN(ch->level, 200));
+	return;
+}
+
+CH_CMD(do_autostance)
+{
+	char arg[MIL];
+
+	if (IS_NPC(ch))
+		return;
+
+	argument = one_argument(argument, arg);
+
+	if (!str_cmp(arg, "none"))
+	{
+		chprintln(ch, "You no longer autostance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_NONE);
+	}
+	else if (!str_cmp(arg, "normal"))
+	{
+		chprintln(ch, "You now autostance into a normal stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_NORMAL);
+	}
+	else if (!str_cmp(arg, "viper"))
+	{
+		chprintln(ch, "You now autostance into the viper stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_VIPER);
+	}
+	else if (!str_cmp(arg, "crane"))
+	{
+		chprintln(ch, "You now autostance into the crane stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_CRANE);
+	}
+	else if (!str_cmp(arg, "crab"))
+	{
+		chprintln(ch, "You now autostance into the crab stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_CRAB);
+	}
+	else if (!str_cmp(arg, "mongoose"))
+	{
+		chprintln(ch, "You now autostance into the mongoose stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_MONGOOSE);
+	}
+	else if (!str_cmp(arg, "bull"))
+	{
+		chprintln(ch, "You now autostance into the bull stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_BULL);
+	}
+	else if (!str_cmp(arg, "mantis") && GET_STANCE(ch, STANCE_CRANE) >= 200
+			 && GET_STANCE(ch, STANCE_VIPER) >= 200)
+	{
+		chprintln(ch, "You now autostance into the mantis stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_MANTIS);
+	}
+	else if (!str_cmp(arg, "monkey") && GET_STANCE(ch, STANCE_CRANE) >= 200
+			 && GET_STANCE(ch, STANCE_MONGOOSE) >= 200)
+	{
+		chprintln(ch, "You now autostance into the monkey stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_MONKEY);
+	}
+	else if (!str_cmp(arg, "swallow") && GET_STANCE(ch, STANCE_CRAB) >= 200
+			 && GET_STANCE(ch, STANCE_MONGOOSE) >= 200)
+	{
+		chprintln(ch, "You now autostance into the swallow stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_SWALLOW);
+	}
+	else if (!str_cmp(arg, "tiger") && GET_STANCE(ch, STANCE_BULL) >= 200
+			 && GET_STANCE(ch, STANCE_VIPER) >= 200)
+	{
+		chprintln(ch, "You now autostance into the tiger stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_TIGER);
+	}
+	else if (!str_cmp(arg, "dragon") && GET_STANCE(ch, STANCE_CRAB) >= 200
+			 && GET_STANCE(ch, STANCE_BULL) >= 200)
+	{
+		chprintln(ch, "You now autostance into the dragon stance.");
+		SET_STANCE(ch, STANCE_AUTODROP, STANCE_DRAGON);
+	}
+	else
+		chprintln(ch, "You can't set your autostance to that!");
+}
+
+void autodrop(CHAR_DATA * ch)
+{
+	int stance;
+
+	stance = GET_STANCE(ch, STANCE_AUTODROP);
+
+	if (!IS_VALID_STANCE(stance))
+		return;
+
+	if (!IS_VALID_STANCE(GET_STANCE(ch, STANCE_CURRENT)))
+	{
+		SET_STANCE(ch, STANCE_CURRENT, stance);
+		chprintlnf(ch, "You autodrop into the %s stance. (%d%%)",
+				   get_stance_name(stance), GET_STANCE(ch, stance));
+		act("$n autodrops into the $T stance.", ch, NULL,
+			get_stance_name(stance), TO_ROOM);
+	}
 }
Only in new: fileio.c
diff -ur -x config -x o -x rom src/flags.c new/flags.c
--- src/flags.c	Tue May 27 02:46:36 2003
+++ new/flags.c	Sun Aug 31 19:23:20 2003
@@ -22,17 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "tables.h"
 #include "interp.h"
@@ -55,7 +48,7 @@
 	if (type == '=' || type == '-' || type == '+')
 		argument = one_argument(argument, word);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		chprintln(ch, "Syntax:");
 		chprintln(ch, "  flag mob  <name> <field> <flags>");
@@ -67,19 +60,19 @@
 		return;
 	}
 
-	if (arg2[0] == '\0')
+	if (IS_NULLSTR(arg2))
 	{
 		chprintln(ch, "What do you wish to set flags on?");
 		return;
 	}
 
-	if (arg3[0] == '\0')
+	if (IS_NULLSTR(arg3))
 	{
 		chprintln(ch, "You need to specify a flag to set.");
 		return;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Which flags do you wish to change?");
 		return;
@@ -196,7 +189,7 @@
 		{
 			argument = one_argument(argument, word);
 
-			if (word[0] == '\0')
+			if (IS_NULLSTR(word))
 				break;
 
 			pos = flag_value(flag_table, word);
Only in new: gcn.h
diff -ur -x config -x o -x rom src/globals.h new/globals.h
--- src/globals.h	Tue May 27 02:46:36 2003
+++ new/globals.h	Sun Aug 31 19:23:21 2003
@@ -22,126 +22,77 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 #if !defined(GLOBALS_H)
 #define GLOBALS_H
 
 #if defined(IN_DB_C)
-#if defined(GLOBAL)
-#undef GLOBAL
-#endif
-#if defined(GLOBAL_DEF)
-#undef GLOBAL_DEF
-#endif
 #define    GLOBAL(str) str
-#define GLOBAL_DEF(str, def) str = def
-
+#define    GLOBAL_DEF(str, def) str = def
+#define    GLOBAL_LIST(data, str) data *str##_first = NULL, *str##_last = NULL
 #else
-#if defined(GLOBAL)
-#undef GLOBAL
-#endif
-#if defined(GLOBAL_DEF)
-#undef GLOBAL_DEF
+#define    GLOBAL(str) EXTERN str
+#define GLOBAL_DEF(str, def) EXTERN str
+#define GLOBAL_LIST(data, str) EXTERN data *str##_first, *str##_last
 #endif
-#define    GLOBAL(str) extern str
-#define GLOBAL_DEF(str, def) extern str
-#endif
-
-GLOBAL_DEF(struct class_type *class_table, NULL);
-GLOBAL_DEF(RACE_DATA * race_first, NULL);
-GLOBAL_DEF(RACE_DATA * race_last, NULL);
-GLOBAL_DEF(struct skill_type *skill_table, NULL);
-GLOBAL_DEF(struct group_type *group_table, NULL);
 
-GLOBAL_DEF(SOCIAL_DATA * social_first, NULL);
-GLOBAL_DEF(SOCIAL_DATA * social_last, NULL);
+GLOBAL_DEF(CLASS_DATA * class_table, NULL);
+GLOBAL_LIST(RACE_DATA, race);
 
-GLOBAL_DEF(int maxSocial, 0);
+GLOBAL_DEF(SKILL_DATA * skill_table, NULL);
+GLOBAL_DEF(GROUP_DATA * group_table, NULL);
 
-GLOBAL_DEF(HELP_DATA * help_first, NULL);
-GLOBAL_DEF(HELP_DATA * help_last, NULL);
+GLOBAL_LIST(SOCIAL_DATA, social);
 
-GLOBAL_DEF(SHOP_DATA * shop_first, NULL);
-GLOBAL_DEF(SHOP_DATA * shop_last, NULL);
+GLOBAL_DEF(int maxSocial, 0);
 
-GLOBAL_DEF(CHAR_DATA * char_first, NULL);
-GLOBAL_DEF(CHAR_DATA * char_last, NULL);
-GLOBAL_DEF(DESCRIPTOR_DATA * descriptor_first, NULL);
-GLOBAL_DEF(DESCRIPTOR_DATA * descriptor_last, NULL);
-GLOBAL_DEF(OBJ_DATA * object_first, NULL);
-GLOBAL_DEF(OBJ_DATA * object_last, NULL);
-GLOBAL_DEF(CHAR_DATA * player_first, NULL);
-GLOBAL_DEF(CHAR_DATA * player_last, NULL);
-
-GLOBAL_DEF(PROG_CODE * mprog_first, NULL);
-GLOBAL_DEF(PROG_CODE * mprog_last, NULL);
-GLOBAL_DEF(PROG_CODE * oprog_first, NULL);
-GLOBAL_DEF(PROG_CODE * oprog_last, NULL);
-GLOBAL_DEF(PROG_CODE * rprog_first, NULL);
-GLOBAL_DEF(PROG_CODE * rprog_last, NULL);
-
-GLOBAL_DEF(AUCTION_DATA * auction_first, NULL);
-GLOBAL_DEF(AUCTION_DATA * auction_last, NULL);
-
-GLOBAL_DEF(STAT_DATA * stat_first, NULL);
-GLOBAL_DEF(STAT_DATA * stat_last, NULL);
-GLOBAL_DEF(BAN_DATA * ban_first, NULL);
-GLOBAL_DEF(BAN_DATA * ban_last, NULL);
+GLOBAL_LIST(HELP_DATA, help);
+GLOBAL_LIST(SHOP_DATA, shop);
+GLOBAL_LIST(CHAR_DATA, char);
+GLOBAL_LIST(DESCRIPTOR_DATA, descriptor);
+GLOBAL_LIST(OBJ_DATA, object);
+GLOBAL_LIST(CHAR_DATA, player);
+GLOBAL_LIST(PROG_CODE, mprog);
+GLOBAL_LIST(PROG_CODE, oprog);
+GLOBAL_LIST(PROG_CODE, rprog);
+GLOBAL_LIST(AUCTION_DATA, auction);
+GLOBAL_LIST(STAT_DATA, stat);
+GLOBAL_LIST(BAN_DATA, ban);
 
 GLOBAL(char bug_buf[MSL]);
 GLOBAL_DEF(time_t current_time, 0);
-GLOBAL_DEF(bool fLogAll, FALSE);
 GLOBAL_DEF(FILE * fpReserve, NULL);
 GLOBAL(KILL_DATA kill_table[MAX_LEVEL]);
 GLOBAL(char log_buf[MSL]);
 GLOBAL(TIME_INFO_DATA time_info);
-GLOBAL(WEATHER_DATA weather_info);
 GLOBAL_DEF(bool MOBtrigger, TRUE);
-GLOBAL_DEF(DISABLED_DATA * disabled_first, NULL);	/* interp.c */
-GLOBAL_DEF(DISABLED_DATA * disabled_last, NULL);	/* interp.c */
+GLOBAL_LIST(DISABLED_DATA, disabled);
 GLOBAL(GQUEST gquest_info);
-GLOBAL(WAR_DATA war_info);
+GLOBAL(WAR war_info);
 GLOBAL_DEF(int maxClan, 0);
 GLOBAL_DEF(int maxCommands, 0);
 GLOBAL_DEF(int maxSkill, 0);
 GLOBAL_DEF(int maxGroup, 0);
 GLOBAL_DEF(int maxRace, 0);
 GLOBAL_DEF(int maxClass, 0);
-GLOBAL_DEF(bool fBootDb, FALSE);
 GLOBAL_DEF(int newmobs, 0);
 GLOBAL_DEF(int newobjs, 0);
-#if (STRHASH==1)
-GLOBAL_DEF(char *string_space, NULL);
 GLOBAL_DEF(int nAllocString, 0);
 GLOBAL_DEF(size_t sAllocString, 0);
-#elif (STRHASH==2)
-GLOBAL_DEF(int str_count, 0);
-GLOBAL_DEF(int str_real_count, 0);
-#endif
 GLOBAL_DEF(CHAR_DATA * char_free, NULL);
 GLOBAL_DEF(PC_DATA * pcdata_free, NULL);
 GLOBAL_DEF(DESCRIPTOR_DATA * descriptor_free, NULL);
 GLOBAL_DEF(OBJ_DATA * obj_free, NULL);
 GLOBAL_DEF(AFFECT_DATA * affect_free, NULL);
 GLOBAL_DEF(MBR_DATA * mbr_free, NULL);
-GLOBAL_DEF(int arena, FIGHT_OPEN);
 GLOBAL_DEF(int maxDeity, 0);
-GLOBAL_DEF(DEITY_DATA * deity_first, NULL);
-GLOBAL_DEF(DEITY_DATA * deity_last, NULL);
-
-GLOBAL_DEF(WPWD_DATA * wpwd_first, NULL);
-GLOBAL_DEF(WPWD_DATA * wpwd_last, NULL);
-
-GLOBAL_DEF(MBR_DATA * mbr_first, NULL);
-GLOBAL_DEF(MBR_DATA * mbr_last, NULL);
-
-GLOBAL_DEF(CLAN_DATA * clan_first, NULL);
-GLOBAL_DEF(CLAN_DATA * clan_last, NULL);
-
-GLOBAL_DEF(CMD_DATA * cmd_first, NULL);
-GLOBAL_DEF(CMD_DATA * cmd_last, NULL);
+GLOBAL_LIST(DEITY_DATA, deity);
+GLOBAL_LIST(WPWD_DATA, wpwd);
+GLOBAL_LIST(MBR_DATA, mbr);
+GLOBAL_LIST(CLAN_DATA, clan);
+GLOBAL_LIST(CMD_DATA, cmd);
 
 GLOBAL(CMD_DATA * command_hash[126]);
 GLOBAL(SOCIAL_DATA * social_hash[27]);
@@ -150,5 +101,90 @@
 
 GLOBAL_DEF(int port, 0);
 GLOBAL(char HOSTNAME[1024]);
+GLOBAL_DEF(RACE_DATA * default_race, NULL);
+GLOBAL_DEF(CHANNEL_DATA * channel_table, NULL);
+GLOBAL_DEF(int maxChannel, 0);
+
+GLOBAL(CRS crs_info);
+GLOBAL(MUD mud_info);
+
+GLOBAL_DEF(SONG_DATA * song_table, NULL);
+GLOBAL_DEF(int maxSongs, 0);
+GLOBAL(char EXE_FILE[1024]);
+GLOBAL(char UNAME[1024]);
+GLOBAL(char CWDIR[1024]);
+GLOBAL_DEF(time_t boot_time, 0);
+
+GLOBAL_LIST(CORPSE_DATA, corpse);
+GLOBAL_LIST(AREA_DATA, area);
+
+EXTERN char *const temp_settings[];	/* FB */
+EXTERN char *const precip_settings[];
+EXTERN char *const wind_settings[];
+EXTERN char *const preciptemp_msg[6][6];
+EXTERN char *const windtemp_msg[6][6];
+EXTERN char *const precip_msg[];
+EXTERN char *const wind_msg[];
+
+/*
+ * Global Constants
+ */
+EXTERN char *const dir_name[];
+EXTERN const int rev_dir[];		/* int - ROM OLC */
+
+/*
+ * Global variables
+ */
+GLOBAL_DEF(int top_affect, 0);
+GLOBAL_DEF(int top_area, 0);
+GLOBAL_DEF(int top_ed, 0);
+GLOBAL_DEF(int top_exit, 0);
+GLOBAL_DEF(int top_help, 0);
+GLOBAL_DEF(int top_mob_index, 0);
+GLOBAL_DEF(int top_obj_index, 0);
+GLOBAL_DEF(int top_reset, 0);
+GLOBAL_DEF(int top_room, 0);
+GLOBAL_DEF(int top_explored, 0);
+GLOBAL_DEF(int top_shop, 0);
+
+GLOBAL_DEF(vnum_t top_vnum_mob, 0);
+GLOBAL_DEF(vnum_t top_vnum_obj, 0);
+GLOBAL_DEF(vnum_t top_vnum_room, 0);
+GLOBAL_DEF(int mobile_count, 0);
+
+EXTERN MOB_INDEX_DATA *mob_index_hash[MAX_KEY_HASH];
+EXTERN OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
+EXTERN ROOM_INDEX_DATA *room_index_hash[MAX_KEY_HASH];
+
+#if !defined(NO_WEB)
+GLOBAL_DEF(bool WebUP, FALSE);
+GLOBAL(const char *www_history[20]);
+GLOBAL_DEF(int www_index, 0);
+#endif
+
+/*
+ * Global constants.
+ */
+EXTERN const struct str_app_type str_app[26];
+EXTERN const struct int_app_type int_app[26];
+EXTERN const struct wis_app_type wis_app[26];
+EXTERN const struct dex_app_type dex_app[26];
+EXTERN const struct con_app_type con_app[26];
+
+EXTERN const struct weapon_type weapon_table[];
+EXTERN const struct item_type item_table[];
+EXTERN const struct wiznet_type wiznet_table[];
+EXTERN const struct attack_type attack_table[];
+EXTERN const struct spec_type spec_table[];
+EXTERN const struct liq_type liq_table[];
+
+GLOBAL_DEF(int control, 0);
+GLOBAL_DEF(const char *help_greeting, "Welcome to " MUD_NAME);
+GLOBAL(runlevel_t run_level);
+GLOBAL_DEF(int top_mprog_index, 0);
+GLOBAL_DEF(int top_oprog_index, 0);
+GLOBAL_DEF(int top_rprog_index, 0);
+
+GLOBAL_DEF(int telopt_lskip, 0);
 
 #endif
diff -ur -x config -x o -x rom src/gquest.c new/gquest.c
--- src/gquest.c	Tue May 27 02:46:36 2003
+++ new/gquest.c	Sun Aug 31 19:23:20 2003
@@ -22,14 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "recycle.h"
 
@@ -88,7 +83,7 @@
 	argument = one_argument(argument, arg2);
 	argument = one_argument(argument, arg3);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || IS_NULLSTR(arg3))
 	{
 		chprintln(ch, "Syntax: gquest start <min level> <max level> <#mobs>");
 		return FALSE;
@@ -161,8 +156,7 @@
 	gquest_info.minlevel = blevel;
 	gquest_info.maxlevel = elevel;
 	gquest_info.mob_count = mobs;
-	free_string(gquest_info.who);
-	gquest_info.who = str_dup(ch->name);
+	replace_string(gquest_info.who, ch->name);
 	if (!generate_gquest(ch))
 	{
 		if (!IS_IMMORTAL(ch))
@@ -181,16 +175,17 @@
 
 void auto_gquest(void)
 {
-	CHAR_DATA *wch = NULL, *registar = NULL;
+	CHAR_DATA *wch = NULL;
+	static CHAR_DATA *registar = NULL;
 	int middle = MAX_MORTAL_LEVEL / 2, maxlvl = 0;
 	int minlvl = MAX_LEVEL, count = 0, lbonus = 0, half = 0;
 
 	if (gquest_info.running != GQUEST_OFF)
 		return;
 
-	for (wch = char_first; wch != NULL; wch = wch->next)
+	for (wch = player_first; wch != NULL; wch = wch->next_player)
 	{
-		if (!IS_NPC(wch) && !IS_IMMORTAL(wch))
+		if (!IS_IMMORTAL(wch))
 		{
 			count++;
 			maxlvl = UMAX(maxlvl, wch->level);
@@ -212,20 +207,22 @@
 	minlvl = number_range(minlvl, middle - lbonus);
 	maxlvl = number_range(middle + lbonus, maxlvl);
 	/* find the registar mob if he exits, (not needed only put in for RP aspects) */
-	for (registar = char_first; registar != NULL; registar = registar->next)
+	if (registar == NULL)
 	{
-		if (!IS_NPC(registar))
-			continue;
-		if (registar->pIndexData->vnum == MOB_VNUM_REGISTAR)
-			break;
+		for (registar = char_first; registar != NULL; registar = registar->next)
+		{
+			if (!IS_NPC(registar))
+				continue;
+			if (registar->pIndexData->vnum == MOB_VNUM_REGISTAR)
+				break;
+		}
 	}
 	gquest_info.running = GQUEST_WAITING;
 	gquest_info.mob_count = number_range(5, 30 - lbonus);
 	gquest_info.minlevel = UMAX(1, minlvl);
 	gquest_info.maxlevel = UMIN(MAX_MORTAL_LEVEL, maxlvl);
-	free_string(gquest_info.who);
-	gquest_info.who =
-		!registar ? str_dup("AutoQuest (tm)") : str_dup(registar->short_descr);
+	replace_string(gquest_info.who,
+				   !registar ? "AutoQuest" : registar->short_descr);
 	generate_gquest(registar);
 	return;
 }
@@ -233,12 +230,11 @@
 void post_gquest(CHAR_DATA * ch)
 {
 	BUFFER *output;
-	GQ_LIST *gql;
+	GQ_DATA *gql;
 	MOB_INDEX_DATA *mob;
 	int i;
 	GQUEST_HIST *hist;
 	char shortd[MAX_INPUT_LENGTH];
-	char buf[MAX_STRING_LENGTH];
 
 	if (gquest_info.running == GQUEST_OFF || gquest_info.involved == 0)
 		return;
@@ -249,39 +245,31 @@
 			gquest_info.maxlevel, gquest_info.mob_count, ch->name);
 	hist->short_descr = str_dup(shortd);
 	output = new_buf();
-	sprintf(buf, "GLOBAL QUEST INFO\n\r-----------------\n\r");
-	add_buf(output, buf);
-	sprintf(buf, "Started by  : %s\n\r",
-			gquest_info.who[0] == '\0' ? "Unknown" : gquest_info.who);
-	add_buf(output, buf);
-	sprintf(buf, "Levels      : %d - %d\n\r", gquest_info.minlevel,
-			gquest_info.maxlevel);
-	add_buf(output, buf);
-	sprintf(buf, "Those Playing\n\r-------------\n\r");
-	add_buf(output, buf);
+	bprintln(output, "GLOBAL QUEST INFO\n\r-----------------");
+	bprintlnf(output, "Started by  : %s",
+			  IS_NULLSTR(gquest_info.who) ? "Unknown" : gquest_info.who);
+	bprintlnf(output, "Levels      : %d - %d", gquest_info.minlevel,
+			  gquest_info.maxlevel);
+	bprintln(output, "Those Playing\n\r-------------");
 	for (gql = gquest_info.first; gql != NULL; gql = gql->next)
 		if (gql->ch != ch)
-			sprintf(buf, "%s [%d mobs left]\n\r", gql->ch->name,
-					gquest_info.mob_count - count_gqmobs(gql));
-	add_buf(output, buf);
-	sprintf(buf, "%s won the GQuest.\n\r", ch->name);
-	add_buf(output, buf);
-	sprintf(buf, "Quest Rewards\n\r-------------\n\r");
-	add_buf(output, buf);
-	sprintf(buf, "Qp Reward   : %d + 3 QPs for each target.\n\r",
-			gquest_info.qpoints);
-	add_buf(output, buf);
-	sprintf(buf, "Gold Reward : %d\n\r", gquest_info.gold);
-	add_buf(output, buf);
-	sprintf(buf, "Quest Targets\n\r-------------\n\r");
-	add_buf(output, buf);
+			bprintlnf(output, "%s [%d mobs left]", gql->ch->name,
+					  gquest_info.mob_count - count_gqmobs(gql));
+	bprintlnf(output, "%s won the GQuest.", ch->name);
+	bprintln(output, "Quest Rewards\n\r-------------");
+	bprintlnf(output, "Qp Reward   : %d + 3 QPs for each target.",
+			  gquest_info.qpoints);
+	bprintlnf(output, "Gold Reward : %d", gquest_info.gold);
+	bprintln(output, "Quest Targets\n\r-------------");
 	for (i = 0; i < gquest_info.mob_count; i++)
 	{
+		if (gquest_info.mobs[i] < 0)
+			continue;
+
 		if ((mob = get_mob_index(gquest_info.mobs[i])) != NULL)
 		{
-			sprintf(buf, "%2d) [%-20s] %-30s (level %3d)\n\r", i + 1,
-					mob->area->name, mob->short_descr, mob->level);
-			add_buf(output, buf);
+			bprintlnf(output, "%2d) [%-20s] %-30s (level %3d)", i + 1,
+					  mob->area->name, mob->short_descr, mob->level);
 		}
 	}
 	hist->text = str_dup(buf_string(output));
@@ -292,13 +280,13 @@
 
 void new_gqlist(CHAR_DATA * ch)
 {
-	GQ_LIST *gql;
+	GQ_DATA *gql;
 	int i;
 
 	if (!ch)
 		return;
 
-	alloc_mem(gql, GQ_LIST, 1);
+	alloc_mem(gql, GQ_DATA, 1);
 	alloc_mem(gql->gq_mobs, vnum_t, gquest_info.mob_count);
 	for (i = 0; i < gquest_info.mob_count; i++)
 		gql->gq_mobs[i] = gquest_info.mobs[i];
@@ -308,11 +296,11 @@
 	return;
 }
 
-void free_gqlist(GQ_LIST * gql)
+void free_gqlist(GQ_DATA * gql)
 {
 	free_mem(gql->gq_mobs);
-	gql->ch->gquest = NULL;
-	gql->ch = NULL;
+	if (gql->ch)
+		gql->ch->gquest = NULL;
 	UNLINK(gql, gquest_info.first, gquest_info.last, next, prev);
 	free_mem(gql);
 }
@@ -320,7 +308,6 @@
 CH_CMD(do_gquest)
 {
 	char arg1[MAX_INPUT_LENGTH];
-	char buf[MAX_STRING_LENGTH];
 	CHAR_DATA *wch;
 	MOB_INDEX_DATA *mob;
 	int i = 0;
@@ -334,7 +321,7 @@
 
 	argument = one_argument(argument, arg1);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		chprintln(ch, "Syntax: gquest join     - join a global quest\n\r"
 				  "        gquest quit     - quit the global quest\n\r"
@@ -386,18 +373,17 @@
 
 		output = new_buf();
 
-		if (argument[0] == '\0')
+		if (IS_NULLSTR(argument))
 		{
-			add_buf(output,
-					"Num Finished Time            Levels  Mobs Completed by\n\r"
-					"--- ------------------------ ------- ---- ------------\n\r");
+			bprintln(output,
+					 "Num Finished Time            Levels  Mobs Completed by\n\r"
+					 "--- ------------------------ ------- ---- ------------");
 			for (hist = gqhist_first; hist != NULL; hist = hist->next)
 			{
-				sprintf(buf, "%2d) ", ++count);
-				add_buf(output, buf);
-				add_buf(output, hist->short_descr);
+				bprintf(output, "%2d) ", ++count);
+				bprint(output, hist->short_descr);
 			}
-			add_buf(output, "Type 'gquest hist #' to view details.\n\r");
+			bprintln(output, "Type 'gquest hist #' to view details.");
 		}
 		else
 		{
@@ -412,14 +398,14 @@
 			for (hist = gqhist_first; hist != NULL; hist = hist->next)
 				if (++count == atoi(argument))
 				{
-					add_buf(output, hist->text);
+					bprint(output, hist->text);
 					found = TRUE;
 				}
 
 			if (!found)
-				add_buf(output, "History data not found.");
+				bprintln(output, "History data not found.");
 		}
-		page_to_char(buf_string(output), ch);
+		sendpage(ch, buf_string(output));
 		free_buf(output);
 		return;
 	}
@@ -443,7 +429,6 @@
 	}
 	else if (!str_prefix(arg1, "join"))
 	{
-		/* see dlm_quest.c */
 		if (IS_QUESTOR(ch))
 		{
 			chprintln(ch, "Why don't you finish your other quest first.");
@@ -496,48 +481,44 @@
 	{
 		output = new_buf();
 
-		add_buf(output, "[ GLOBAL QUEST INFO ]\n\r");
-		sprintf(buf, "Started by  : %s\n\r",
-				gquest_info.who[0] == '\0' ? "Unknown" : gquest_info.who);
-		add_buf(output, buf);
-		sprintf(buf, "Playing     : %d player%s.\n\r",
-				gquest_info.involved, gquest_info.involved == 1 ? "" : "s");
-		add_buf(output, buf);
-		sprintf(buf, "Levels      : %d - %d\n\r", gquest_info.minlevel,
-				gquest_info.maxlevel);
-		add_buf(output, buf);
-		sprintf(buf, "Status      : %s for %d minute%s.\n\r",
-				gquest_info.running ==
-				GQUEST_WAITING ? "Waiting" : "Running",
-				gquest_info.timer, gquest_info.timer == 1 ? "" : "s");
-		add_buf(output, buf);
-		add_buf(output, "[ Quest Rewards ]\n\r");
-		sprintf(buf, "Qp Reward   : %d\n\r", gquest_info.qpoints);
-		add_buf(output, buf);
-		sprintf(buf, "Gold Reward : %d\n\r", gquest_info.gold);
-		add_buf(output, buf);
-		add_buf(output, "[ Quest Targets ]\n\r");
+		bprintln(output, "[ GLOBAL QUEST INFO ]");
+		bprintlnf(output, "Started by  : %s",
+				  IS_NULLSTR(gquest_info.who) ? "Unknown" : gquest_info.who);
+		bprintlnf(output, "Playing     : %d player%s.",
+				  gquest_info.involved, gquest_info.involved == 1 ? "" : "s");
+		bprintlnf(output, "Levels      : %d - %d", gquest_info.minlevel,
+				  gquest_info.maxlevel);
+		bprintlnf(output, "Status      : %s for %d minute%s.",
+				  gquest_info.running ==
+				  GQUEST_WAITING ? "Waiting" : "Running",
+				  gquest_info.timer, gquest_info.timer == 1 ? "" : "s");
+		bprintln(output, "[ Quest Rewards ]");
+		bprintlnf(output, "Qp Reward   : %d", gquest_info.qpoints);
+		bprintlnf(output, "Gold Reward : %d", gquest_info.gold);
+		bprintln(output, "[ Quest Targets ]");
 		for (i = 0; i < gquest_info.mob_count; i++)
 		{
+			if (gquest_info.mobs[i] < 0)
+				continue;
+
 			if ((mob = get_mob_index(gquest_info.mobs[i])) != NULL)
 			{
-				sprintf(buf,
-						"%2d) [%-20s] %-30s (level %3d)\n\r",
-						i + 1, mob->area->name,
-						smash_colour(mob->short_descr), mob->level);
-				add_buf(output, buf);
+				bprintlnf(output,
+						  "%2d) [%-20s] %-30s (level %3d)",
+						  i + 1, mob->area->name,
+						  smash_colour(mob->short_descr), mob->level);
 			}
 		}
-		page_to_char(buf_string(output), ch);
+		sendpage(ch, buf_string(output));
 		free_buf(output);
 		return;
 	}
 	else if (!str_prefix(arg1, "time"))
 	{
 		if (gquest_info.running == GQUEST_OFF)
-			sprintf(buf,
-					"THe next Global Quest will start in %d minute%s.\n\r",
-					gquest_info.timer, gquest_info.timer == 1 ? "" : "s");
+			chprintlnf(ch,
+					   "The next Global Quest will start in %d minute%s.\n\r",
+					   gquest_info.timer, gquest_info.timer == 1 ? "" : "s");
 		else
 			chprintlnf(ch, "The Global Quest is %s for %d minute%s.",
 					   gquest_info.running ==
@@ -547,7 +528,7 @@
 	}
 	else if (!str_prefix(arg1, "progress"))
 	{
-		GQ_LIST *gql;
+		GQ_DATA *gql;
 
 		if (gquest_info.running != GQUEST_RUNNING)
 		{
@@ -570,7 +551,7 @@
 	{
 		int count = 0;
 
-		if (IS_IMMORTAL(ch) && argument[0] != '\0')
+		if (IS_IMMORTAL(ch) && !IS_NULLSTR(argument))
 		{
 			if ((wch = get_char_world(ch, argument)) == NULL || IS_NPC(wch))
 			{
@@ -589,23 +570,24 @@
 		}
 
 		output = new_buf();
-		sprintf(buf, "[ %s have %d of %d mobs left ]\n\r",
-				wch == ch ? "You" : wch->name,
-				gquest_info.mob_count - count_gqmobs(wch->gquest),
-				gquest_info.mob_count);
-		add_buf(output, buf);
+		bprintlnf(output, "[ %s have %d of %d mobs left ]",
+				  wch == ch ? "You" : wch->name,
+				  gquest_info.mob_count - count_gqmobs(wch->gquest),
+				  gquest_info.mob_count);
 		for (i = 0; i < gquest_info.mob_count; i++)
 		{
+			if (wch->gquest->gq_mobs[i] == -1)
+				continue;
+
 			if ((mob = get_mob_index(wch->gquest->gq_mobs[i])) != NULL)
 			{
 				count++;
-				sprintf(buf,
-						"%2d) [%-20s] %-30s (level %3d)\n\r",
-						count, mob->area->name, mob->short_descr, mob->level);
-				add_buf(output, buf);
+				bprintlnf(output,
+						  "%2d) [%-20s] %-30s (level %3d)",
+						  count, mob->area->name, mob->short_descr, mob->level);
 			}
 		}
-		page_to_char(buf_string(output), ch);
+		sendpage(ch, buf_string(output));
 		free_buf(output);
 		return;
 	}
@@ -633,10 +615,9 @@
 		chprintlnf(ch, "You receive %d gold and %d quest points.",
 				   gquest_info.gold, gquest_info.qpoints);
 		end_gquest(gquest_info.last_registar);
-		sprintf(buf,
-				"$n has completed the global quest, next gquest in %d minutes.",
-				gquest_info.timer);
-		announce(ch, INFO_GQUEST, buf);
+		announce(ch, INFO_GQUEST,
+				 "$n has completed the global quest, next gquest in %d minutes.",
+				 gquest_info.timer);
 		return;
 	}
 	else
@@ -646,11 +627,10 @@
 
 void end_gquest(CHAR_DATA * who)
 {
-	GQ_LIST *gql, *gql_next;
+	GQ_DATA *gql, *gql_next;
 
 	gquest_info.running = GQUEST_OFF;
-	free_string(gquest_info.who);
-	gquest_info.who = str_dup("");
+	replace_string(gquest_info.who, "");
 	gquest_info.mob_count = 0;
 	gquest_info.timer = number_range(100, 200);
 	gquest_info.involved = 0;
@@ -754,7 +734,6 @@
 	CHAR_DATA *victim = NULL;
 	vnum_t *vnums;
 	int mob_count, randm;
-	char buf[MAX_STRING_LENGTH];
 	int i;
 
 	mob_count = 0;
@@ -811,20 +790,18 @@
 	gquest_info.qpoints = number_range(15, 30) * gquest_info.mob_count;
 	gquest_info.gold = number_range(100, 150) * gquest_info.mob_count;
 	gquest_info.timer = 3;
-	sprintf(buf,
-			"%s Global Quest for levels %d to %d%s.  Type 'GQUEST INFO' to see the quest.",
-			!who ? "A" : "$n announces a", gquest_info.minlevel,
-			gquest_info.maxlevel, !who ? " has started" : "");
-	announce(who, INFO_GQUEST, buf);
-	chprintlnf(who,
-			   "You announce a Global Quest for levels %d to %d with %d targets.\n\r",
-			   gquest_info.minlevel, gquest_info.maxlevel,
-			   gquest_info.mob_count);
+	announce(who, INFO_GQUEST,
+			 "%s Global Quest for levels %d to %d%s.  Type 'GQUEST INFO' to see the quest.",
+			 !who ? "A" : "$n announces a", gquest_info.minlevel,
+			 gquest_info.maxlevel, !who ? " has started" : "");
+	announce(who, INFO_GQUEST | INFO_PRIVATE,
+			 "You announce a Global Quest for levels %d to %d with %d targets.\n\r",
+			 gquest_info.minlevel, gquest_info.maxlevel, gquest_info.mob_count);
 	free_mem(vnums);
 	return TRUE;
 }
 
-int is_gqmob(GQ_LIST * gql, vnum_t vnum)
+int is_gqmob(GQ_DATA * gql, vnum_t vnum)
 {
 	int i;
 
@@ -848,7 +825,7 @@
 	return -1;
 }
 
-int count_gqmobs(GQ_LIST * gql)
+int count_gqmobs(GQ_DATA * gql)
 {
 	int i, count = 0;
 
@@ -869,7 +846,7 @@
 	if (gquest_info.running == GQUEST_OFF)
 		return FALSE;
 
-	if (get_mob_index(vnum) == NULL)
+	if (vnum == -1 || get_mob_index(vnum) == NULL)
 		return FALSE;
 
 	for (i = 0; i < gquest_info.mob_count; i++)
diff -ur -x config -x o -x rom src/gsn.h new/gsn.h
--- src/gsn.h	Tue May 27 02:46:36 2003
+++ new/gsn.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 #if !defined(GSN_H)
@@ -41,7 +41,7 @@
 #if defined(MAKE_GSN_TABLE)
 #define    GSN(gsn) { #gsn, &gsn },
 #else
-#define	GSN(gsn) extern int gsn;
+#define	GSN(gsn) EXTERN int gsn;
 #endif
 #endif
 
Only in new: h
diff -ur -x config -x o -x rom src/handler.c new/handler.c
--- src/handler.c	Tue May 27 02:46:36 2003
+++ new/handler.c	Sun Aug 31 19:23:20 2003
@@ -22,15 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "magic.h"
@@ -40,7 +35,7 @@
 /*
  * Local functions.
  */
-void affect_modify args((CHAR_DATA * ch, AFFECT_DATA * paf, bool fAdd));
+PROTOTYPE(void affect_modify, (CHAR_DATA *, AFFECT_DATA *, bool));
 
 /* friend stuff -- for NPC's mostly */
 bool is_friend(CHAR_DATA * ch, CHAR_DATA * victim)
@@ -348,7 +343,7 @@
 
 	else if (sn < -1 || sn > maxSkill)
 	{
-		bug("Bad sn %d in get_skill.", sn);
+		bugf("Bad sn %d in get_skill.", sn);
 		skill = 0;
 	}
 
@@ -521,7 +516,7 @@
 		/* do a FULL reset */
 		for (loc = 0; loc < MAX_WEAR; loc++)
 		{
-			obj = get_eq_char(ch, loc);
+			obj = get_eq_char(ch, (wloc_t) loc);
 			if (obj == NULL)
 				continue;
 			if (!obj->enchanted)
@@ -545,6 +540,8 @@
 					case APPLY_MOVE:
 						ch->max_move -= mod;
 						break;
+					default:
+						break;
 					}
 				}
 
@@ -565,6 +562,8 @@
 				case APPLY_MOVE:
 					ch->max_move -= mod;
 					break;
+				default:
+					break;
 				}
 			}
 		}
@@ -604,11 +603,11 @@
 	/* now start adding back the effects */
 	for (loc = 0; loc < MAX_WEAR; loc++)
 	{
-		obj = get_eq_char(ch, loc);
+		obj = get_eq_char(ch, (wloc_t) loc);
 		if (obj == NULL)
 			continue;
 		for (i = 0; i < 4; i++)
-			ch->armor[i] -= apply_ac(obj, loc, i);
+			ch->armor[i] -= apply_ac(obj, (wloc_t) loc, i);
 
 		if (!obj->enchanted)
 			for (af = obj->pIndexData->first_affect; af != NULL; af = af->next)
@@ -671,6 +670,8 @@
 				case APPLY_SAVING_SPELL:
 					ch->saving_throw += mod;
 					break;
+				default:
+					break;
 				}
 			}
 
@@ -734,6 +735,8 @@
 			case APPLY_SAVING_SPELL:
 				ch->saving_throw += mod;
 				break;
+			default:
+				break;
 			}
 		}
 	}
@@ -799,6 +802,8 @@
 		case APPLY_SAVING_SPELL:
 			ch->saving_throw += mod;
 			break;
+		default:
+			break;
 		}
 	}
 
@@ -913,11 +918,11 @@
 	const char *list, *string;
 
 	/* fix crash on NULL namelist */
-	if (namelist == NULL || namelist[0] == '\0')
+	if (IS_NULLSTR(namelist))
 		return FALSE;
 
 	/* fixed to prevent is_name on "" returning TRUE */
-	if (str[0] == '\0')
+	if (IS_NULLSTR(str))
 		return FALSE;
 
 	string = str;
@@ -926,7 +931,7 @@
 	{
 		str = one_argument(str, part);
 
-		if (part[0] == '\0')
+		if (IS_NULLSTR(part))
 			return TRUE;
 
 		/* check to see if this is part of namelist */
@@ -934,7 +939,7 @@
 		for (;;)				/* start parsing namelist */
 		{
 			list = one_argument(list, name);
-			if (name[0] == '\0')	/* this name was not found */
+			if (IS_NULLSTR(name))	/* this name was not found */
 				return FALSE;
 
 			if (!str_prefix(string, name))
@@ -956,7 +961,7 @@
 	for (;;)
 	{
 		namelist = one_argument(namelist, name);
-		if (name[0] == '\0')
+		if (IS_NULLSTR(name))
 			return FALSE;
 		if (!str_cmp(str, name))
 			return TRUE;
@@ -1015,6 +1020,8 @@
 		case TO_VULN:
 			SET_BIT(ch->vuln_flags, paf->bitvector);
 			break;
+		default:
+			break;
 		}
 	}
 	else
@@ -1033,6 +1040,8 @@
 		case TO_VULN:
 			REMOVE_BIT(ch->vuln_flags, paf->bitvector);
 			break;
+		default:
+			break;
 		}
 		mod = 0 - mod;
 	}
@@ -1040,7 +1049,7 @@
 	switch (paf->location)
 	{
 	default:
-		bug("Affect_modify: unknown location %d.", paf->location);
+		bugf("Affect_modify: unknown location %d.", paf->location);
 		return;
 
 	case APPLY_NONE:
@@ -1154,7 +1163,7 @@
 }
 
 /* fix object affects when removing one */
-void affect_check(CHAR_DATA * ch, int where, flag_t vector)
+void affect_check(CHAR_DATA * ch, where_t where, flag_t vector)
 {
 	AFFECT_DATA *paf;
 	OBJ_DATA *obj;
@@ -1179,6 +1188,8 @@
 			case TO_VULN:
 				SET_BIT(ch->vuln_flags, vector);
 				break;
+			default:
+				break;
 			}
 			return;
 		}
@@ -1204,7 +1215,8 @@
 					break;
 				case TO_VULN:
 					SET_BIT(ch->vuln_flags, vector);
-
+				default:
+					break;
 				}
 				return;
 			}
@@ -1229,6 +1241,8 @@
 				case TO_VULN:
 					SET_BIT(ch->vuln_flags, vector);
 					break;
+				default:
+					break;
 				}
 				return;
 			}
@@ -1276,6 +1290,8 @@
 			if (obj->item_type == ITEM_WEAPON)
 				SET_BIT(obj->value[4], paf->bitvector);
 			break;
+		default:
+			break;
 		}
 
 	return;
@@ -1286,12 +1302,12 @@
  */
 void affect_remove(CHAR_DATA * ch, AFFECT_DATA * paf)
 {
-	int where;
+	where_t where;
 	flag_t vector;
 
 	if (ch->first_affect == NULL)
 	{
-		bug("Affect_remove: no affect.", 0);
+		bug("Affect_remove: no affect.");
 		return;
 	}
 
@@ -1309,12 +1325,12 @@
 
 void affect_remove_obj(OBJ_DATA * obj, AFFECT_DATA * paf)
 {
-	int where;
+	where_t where;
 	flag_t vector;
 
 	if (obj->first_affect == NULL)
 	{
-		bug("Affect_remove_object: no affect.", 0);
+		bug("Affect_remove_object: no affect.");
 		return;
 	}
 
@@ -1335,6 +1351,8 @@
 			if (obj->item_type == ITEM_WEAPON)
 				REMOVE_BIT(obj->value[4], paf->bitvector);
 			break;
+		default:
+			break;
 		}
 
 	UNLINK(paf, obj->first_affect, obj->last_affect, next, prev);
@@ -1414,7 +1432,7 @@
 
 	if (ch->in_room == NULL)
 	{
-		bug("Char_from_room: NULL.", 0);
+		bug("Char_from_room: NULL.");
 		return;
 	}
 
@@ -1446,7 +1464,7 @@
 	{
 		ROOM_INDEX_DATA *room;
 
-		bug("Char_to_room: NULL.", 0);
+		bug("Char_to_room: NULL.");
 
 		if ((room = get_room_index(ROOM_VNUM_TEMPLE)) != NULL)
 			char_to_room(ch, room);
@@ -1468,6 +1486,7 @@
 		++ch->in_room->area->nplayer;
 		if (!IS_SET(ch->in_room->room_flags, ROOM_NOEXPLORE))
 			STR_SET_BIT(ch->pcdata->explored, ch->in_room->vnum);
+		portal_map(ch, ch->in_room);
 	}
 
 	if ((obj = get_eq_char(ch, WEAR_LIGHT)) != NULL &&
@@ -1587,7 +1606,7 @@
 
 	if ((ch = obj->carried_by) == NULL)
 	{
-		bug("Obj_from_char: null ch.", 0);
+		bug("Obj_from_char: null ch.");
 		return;
 	}
 
@@ -1607,7 +1626,7 @@
 /*
  * Find the ac value of an obj, including position effect.
  */
-int apply_ac(OBJ_DATA * obj, int iWear, int type)
+int apply_ac(OBJ_DATA * obj, wloc_t iWear, int type)
 {
 	if (obj->item_type != ITEM_ARMOR)
 		return 0;
@@ -1642,6 +1661,8 @@
 		return obj->value[type];
 	case WEAR_HOLD:
 		return obj->value[type];
+	default:
+		break;
 	}
 
 	return 0;
@@ -1650,7 +1671,7 @@
 /*
  * Find a piece of eq on a character.
  */
-OBJ_DATA *get_eq_char(CHAR_DATA * ch, int iWear)
+OBJ_DATA *get_eq_char(CHAR_DATA * ch, wloc_t iWear)
 {
 	OBJ_DATA *obj;
 
@@ -1669,14 +1690,14 @@
 /*
  * Equip a char with an obj.
  */
-void equip_char(CHAR_DATA * ch, OBJ_DATA * obj, int iWear)
+void equip_char(CHAR_DATA * ch, OBJ_DATA * obj, wloc_t iWear)
 {
 	AFFECT_DATA *paf;
 	int i;
 
 	if (get_eq_char(ch, iWear) != NULL)
 	{
-		bug("Equip_char: already equipped (%d).", iWear);
+		bugf("Equip_char: already equipped (%d).", iWear);
 		return;
 	}
 
@@ -1727,13 +1748,13 @@
 
 	if (obj->wear_loc == WEAR_NONE)
 	{
-		bug("Unequip_char: already unequipped.", 0);
+		bug("Unequip_char: already unequipped.");
 		return;
 	}
 
 	for (i = 0; i < 4; i++)
 		ch->armor[i] += apply_ac(obj, obj->wear_loc, i);
-	obj->wear_loc = -1;
+	obj->wear_loc = WEAR_NONE;
 
 	if (!obj->enchanted)
 	{
@@ -1761,7 +1782,7 @@
 	for (paf = obj->first_affect; paf != NULL; paf = paf->next)
 		if (paf->location == APPLY_SPELL_AFFECT)
 		{
-			bug("Norm-Apply: %d", 0);
+			bug("Norm-Apply: %d");
 			for (lpaf = ch->first_affect; lpaf != NULL; lpaf = lpaf_next)
 			{
 				lpaf_next = lpaf->next;
@@ -1769,8 +1790,8 @@
 					(lpaf->level == paf->level) &&
 					(lpaf->location == APPLY_SPELL_AFFECT))
 				{
-					bug("location = %d", lpaf->location);
-					bug("type = %d", lpaf->type);
+					bugf("location = %d", lpaf->location);
+					bugf("type = %d", lpaf->type);
 					affect_remove(ch, lpaf);
 					lpaf_next = NULL;
 				}
@@ -1817,7 +1838,7 @@
 
 	if ((in_room = obj->in_room) == NULL)
 	{
-		bug("obj_from_room: NULL.", 0);
+		bug("obj_from_room: NULL.");
 		return;
 	}
 
@@ -1893,7 +1914,7 @@
 
 	if ((obj_from = obj->in_obj) == NULL)
 	{
-		bug("Obj_from_obj: null obj_from.", 0);
+		bug("Obj_from_obj: null obj_from.");
 		return;
 	}
 
@@ -1960,7 +1981,7 @@
 	/* doesn't seem to be necessary
 	   if ( ch->in_room == NULL )
 	   {
-	   bug( "Extract_char: NULL.", 0 );
+	   bugf( "Extract_char: NULL.", 0 );
 	   return;
 	   }
 	 */
@@ -2052,7 +2073,7 @@
 
 	if (ch && room)
 	{
-		bug("get_char_room received multiple types (ch/room)", 0);
+		bug("get_char_room received multiple types (ch/room)");
 		return NULL;
 	}
 
@@ -2205,7 +2226,7 @@
 
 	if (ch && room)
 	{
-		bug("get_obj_here received a ch and a room", 0);
+		bug("get_obj_here received a ch and a room");
 		return NULL;
 	}
 
@@ -2283,12 +2304,12 @@
 
 	if (ch->gold < 0)
 	{
-		bug("deduct costs: gold %d < 0", ch->gold);
+		bugf("deduct costs: gold %ld < 0", ch->gold);
 		ch->gold = 0;
 	}
 	if (ch->silver < 0)
 	{
-		bug("deduct costs: silver %d < 0", ch->silver);
+		bugf("deduct costs: silver %ld < 0", ch->silver);
 		ch->silver = 0;
 	}
 }
@@ -2303,7 +2324,7 @@
 
 	if (gold < 0 || silver < 0 || (gold == 0 && silver == 0))
 	{
-		bug("Create_money: zero or negative money.", UMIN(gold, silver));
+		bug("Create_money: zero or negative money.");
 		gold = UMAX(1, gold);
 		silver = UMAX(1, silver);
 	}
@@ -2320,8 +2341,7 @@
 	{
 		obj = create_object(get_obj_index(OBJ_VNUM_GOLD_SOME), 0);
 		sprintf(buf, obj->short_descr, gold);
-		free_string(obj->short_descr);
-		obj->short_descr = str_dup(buf);
+		replace_string(obj->short_descr, buf);
 		obj->value[1] = gold;
 		obj->cost = gold;
 		obj->weight = gold / 5;
@@ -2330,8 +2350,7 @@
 	{
 		obj = create_object(get_obj_index(OBJ_VNUM_SILVER_SOME), 0);
 		sprintf(buf, obj->short_descr, silver);
-		free_string(obj->short_descr);
-		obj->short_descr = str_dup(buf);
+		replace_string(obj->short_descr, buf);
 		obj->value[0] = silver;
 		obj->cost = silver;
 		obj->weight = silver / 20;
@@ -2341,8 +2360,7 @@
 	{
 		obj = create_object(get_obj_index(OBJ_VNUM_COINS), 0);
 		sprintf(buf, obj->short_descr, silver, gold);
-		free_string(obj->short_descr);
-		obj->short_descr = str_dup(buf);
+		replace_string(obj->short_descr, buf);
 		obj->value[0] = silver;
 		obj->value[1] = gold;
 		obj->cost = 100 * gold + silver;
@@ -2413,7 +2431,7 @@
 		pRoomIndex->sector_type == SECT_CITY)
 		return FALSE;
 
-	if (weather_info.sunlight == SUN_SET || weather_info.sunlight == SUN_DARK)
+	if (time_info.sunlight == SUN_SET || time_info.sunlight == SUN_DARK)
 		return TRUE;
 
 	return FALSE;
@@ -2421,7 +2439,7 @@
 
 bool is_room_owner(CHAR_DATA * ch, ROOM_INDEX_DATA * room)
 {
-	if (room->owner == NULL || room->owner[0] == '\0')
+	if (IS_NULLSTR(room->owner))
 		return FALSE;
 
 	if (IS_SET(room->area->area_flags, AREA_PLAYER_HOMES))
@@ -2438,7 +2456,7 @@
 	CHAR_DATA *rch;
 	int count;
 
-	if (pRoomIndex->owner != NULL && pRoomIndex->owner[0] != '\0'
+	if (!IS_NULLSTR(pRoomIndex->owner)
 		&& !IS_SET(pRoomIndex->area->area_flags, AREA_PLAYER_HOMES))
 		return TRUE;
 
@@ -2615,7 +2633,7 @@
 	for (;;)
 	{
 		namelist = one_argument(namelist, name);
-		if (name[0] == '\0')
+		if (IS_NULLSTR(name))
 			return FALSE;
 		if (!str_cmp(str, name))
 			return TRUE;
@@ -2666,12 +2684,18 @@
 	{
 #if defined(__CYGWIN__)
 		timet += (time_t) timezone;
+#elif defined(__FreeBSD__)
+		/* hopefully this works */
+		struct tm *ptime;
+		ptime = localtime(&timet);
+		timet += ptime->tm_gmtoff;
 #else
 		timet += timezone;
 #endif
 		timet += (60 * 60 * tzone_table[tz].gmt_offset);
 	}
-	strftime(result, 100, !IS_NULLSTR(format) ? format : "%a %b %d %r %Y",
+	strftime(result, 100,
+			 !IS_NULLSTR(format) ? format : "%a %b %d %I:%M:%S %p %Y",
 			 localtime(&timet));
 
 	return result;
@@ -2713,4 +2737,20 @@
 	sprintf(buf, "%03d", level);
 
 	return buf;
+}
+
+bool file_exists(const char *path, ...)
+{
+	va_list args;
+	char file[1024];
+	struct stat buf;
+
+	if (IS_NULLSTR(path))
+		return FALSE;
+
+	va_start(args, path);
+	vsnprintf(file, sizeof(file), path, args);
+	va_end(args);
+
+	return (stat(file, &buf) != -1 && S_ISREG(buf.st_mode));
 }
diff -ur -x config -x o -x rom src/healer.c new/healer.c
--- src/healer.c	Tue May 27 02:46:36 2003
+++ new/healer.c	Sun Aug 31 19:23:20 2003
@@ -22,15 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <time.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "magic.h"
 #include "interp.h"
@@ -58,7 +53,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		/* display price list */
 		act("$N says 'I offer the following spells:'", ch, NULL, mob, TO_CHAR);
diff -ur -x config -x o -x rom src/hedit.c new/hedit.c
--- src/hedit.c	Tue May 27 02:46:36 2003
+++ new/hedit.c	Sun Aug 31 19:23:20 2003
@@ -22,18 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 
 #include "merc.h"
 #include "tables.h"
@@ -42,9 +33,7 @@
 #include "recycle.h"
 #include "interp.h"
 
-#define HEDIT( fun )           bool fun(CHAR_DATA *ch, const char*argument)
-
-HEDIT(hedit_show)
+OLCED(hedit_show)
 {
 	HELP_DATA *help;
 
@@ -57,7 +46,7 @@
 	return FALSE;
 }
 
-HEDIT(hedit_level)
+OLCED(hedit_level)
 {
 	HELP_DATA *help;
 	int lev;
@@ -83,7 +72,7 @@
 	return TRUE;
 }
 
-HEDIT(hedit_keyword)
+OLCED(hedit_keyword)
 {
 	HELP_DATA *help;
 
@@ -95,14 +84,13 @@
 		return FALSE;
 	}
 
-	free_string(help->keyword);
-	help->keyword = str_dup(argument);
+	replace_string(help->keyword, argument);
 
 	chprintln(ch, "Ok.");
 	return TRUE;
 }
 
-HEDIT(hedit_new)
+OLCED(hedit_new)
 {
 	char arg[MIL], fullarg[MIL];
 	HELP_DATA *help;
@@ -135,7 +123,7 @@
 	return FALSE;
 }
 
-HEDIT(hedit_text)
+OLCED(hedit_text)
 {
 	HELP_DATA *help;
 
@@ -152,31 +140,6 @@
 	return TRUE;
 }
 
-void hedit(CHAR_DATA * ch, char *argument)
-{
-	if (ch->pcdata->security < 9)
-	{
-		chprintln(ch, "HEdit: Insufficient security to modify code.");
-		edit_done(ch);
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		hedit_show(ch, argument);
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, help_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
 CH_CMD(do_hedit)
 {
 	HELP_DATA *pHelp;
@@ -206,7 +169,7 @@
 	return;
 }
 
-HEDIT(hedit_delete)
+OLCED(hedit_delete)
 {
 	HELP_DATA *pHelp;
 	DESCRIPTOR_DATA *d;
@@ -225,9 +188,8 @@
 	return TRUE;
 }
 
-HEDIT(hedit_list)
+OLCED(hedit_list)
 {
-	char buf[MIL];
 	int cnt = 0;
 	HELP_DATA *pHelp;
 	BUFFER *buffer;
@@ -240,16 +202,15 @@
 
 		for (pHelp = help_first; pHelp; pHelp = pHelp->next)
 		{
-			sprintf(buf, "%3d. %-14.14s%s", cnt, pHelp->keyword,
+			bprintf(buffer, "%3d. %-14.14s%s", cnt, pHelp->keyword,
 					cnt % 4 == 3 ? "\n\r" : " ");
-			add_buf(buffer, buf);
 			cnt++;
 		}
 
 		if (cnt % 4)
-			add_buf(buffer, "\n\r");
+			bprintln(buffer, "");
 
-		page_to_char(buf_string(buffer), ch);
+		sendpage(ch, buf_string(buffer));
 		return FALSE;
 	}
 
diff -ur -x config -x o -x rom src/homes.c new/homes.c
--- src/homes.c	Tue May 27 02:46:36 2003
+++ new/homes.c	Sun Aug 31 19:23:20 2003
@@ -22,20 +22,9 @@
 *       By using this code, you have agreed to follow the terms of the    *
 *       ROM license, in the file Rom24/doc/rom.license                    *
 ***************************************************************************
-*     _/_/_/   _/      _/    _/           Devil's Lament MUD              *
-*    _/   _/  _/      _/ _/ _/      (c) 1999-2002 by Ryan Jennings        *
-*   _/   _/  _/      _/    _/          Telnet : <dlmud.com:3778>          *
-*  _/_/_/   _/_/_/  _/    _/           E-Mail : <dlmud@dlmud.com>         *
-*                                   Website: <http://www.dlmud.com/>      *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
+*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#if !defined(WIN32)
-#include <unistd.h>
-#endif
 #include "merc.h"
 #include "interp.h"
 #include "recycle.h"
@@ -58,7 +47,7 @@
 DECLARE_DO_FUN(home_unlink);
 DECLARE_DO_FUN(do_gohome);
 
-void unlink_reset(ROOM_INDEX_DATA * pRoom, RESET_DATA * pReset);
+PROTOTYPE(void unlink_reset, (ROOM_INDEX_DATA *, RESET_DATA *));
 
 #define HOUSE_PRICE 5000000
 #define ROOM_PRICE  3000000
diff -ur -x config -x o -x rom src/hunt.c new/hunt.c
--- src/hunt.c	Tue May 27 02:46:36 2003
+++ new/hunt.c	Sun Aug 31 19:23:20 2003
@@ -22,14 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <time.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "interp.h"
 
@@ -73,24 +68,21 @@
 #define	GO_OK           (!IS_SET( IS_DIR->exit_info, EX_CLOSED ))
 #define	GO_OK_SMARTER   1
 
-void init_hash_table
-args((struct hash_header * ht, int rec_size, int table_size));
-void init_world args((ROOM_INDEX_DATA * room_db[]));
-CHAR_DATA *get_char_area_restrict args((CHAR_DATA * ch, char *argument));
-void destroy_hash_table args((struct hash_header * ht));
-void _hash_enter args((struct hash_header * ht, int key, void *data));
-ROOM_INDEX_DATA *room_find args((ROOM_INDEX_DATA * room_db[], int key));
-void *hash_find args((struct hash_header * ht, int key));
-int room_enter args((ROOM_INDEX_DATA * rb[], int key, ROOM_INDEX_DATA * rm));
-int hash_enter args((struct hash_header * ht, int key, void *data));
-ROOM_INDEX_DATA *room_find_or_create args((ROOM_INDEX_DATA * rb[], int key));
-void *hash_find_or_create args((struct hash_header * ht, int key));
-int room_remove args((ROOM_INDEX_DATA * rb[], int key));
-void *hash_remove args((struct hash_header * ht, int key));
-int exit_ok args((EXIT_DATA * pexit));
-int find_path
-args((int in_room_vnum, int out_room_vnum, CHAR_DATA * ch, int depth,
-	  int in_zone));
+PROTOTYPE(void init_hash_table, (struct hash_header *, int, int));
+PROTOTYPE(void init_world, (ROOM_INDEX_DATA * room_db[]));
+PROTOTYPE(CHAR_DATA * get_char_area_restrict, (CHAR_DATA * ch, char *argument));
+PROTOTYPE(void destroy_hash_table, (struct hash_header *));
+PROTOTYPE(void _hash_enter, (struct hash_header *, int, void *));
+PROTOTYPE(ROOM_INDEX_DATA * room_find, (ROOM_INDEX_DATA * room_db[], int));
+PROTOTYPE(void *hash_find, (struct hash_header *, int));
+PROTOTYPE(int room_enter, (ROOM_INDEX_DATA * rb[], int, ROOM_INDEX_DATA *));
+PROTOTYPE(int hash_enter, (struct hash_header *, int, void *));
+PROTOTYPE(ROOM_INDEX_DATA * room_find_or_create, (ROOM_INDEX_DATA * rb[], int));
+PROTOTYPE(void *hash_find_or_create, (struct hash_header *, int));
+PROTOTYPE(int room_remove, (ROOM_INDEX_DATA * rb[], int));
+PROTOTYPE(void *hash_remove, (struct hash_header *, int));
+PROTOTYPE(int exit_ok, (EXIT_DATA *));
+PROTOTYPE(int find_path, (int, int, CHAR_DATA *, int, int));
 
 void init_hash_table(struct hash_header *ht, int rec_size, int table_size)
 {
@@ -443,7 +435,7 @@
 		return;
 	}
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Whom are you trying to hunt?");
 		return;
Only in new: ignore.c
diff -ur -x config -x o -x rom src/interp.c new/interp.c
--- src/interp.c	Tue May 27 02:46:36 2003
+++ new/interp.c	Sun Aug 31 19:23:20 2003
@@ -22,33 +22,22 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#if !defined(WIN32)
-#include <unistd.h>
-#endif
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
+#include "signals.h"
 
-bool check_social args((CHAR_DATA * ch, char *command, const char *argument));
-bool check_disabled(const struct cmd_type *command);
+PROTOTYPE(bool check_social, (CHAR_DATA *, char *, const char *));
+PROTOTYPE(bool check_disabled, (CHAR_DATA *, CMD_DATA *));
 
 #define END_MARKER	"END"		/* for load_disabled() and save_disabled() */
 
 /*
  * Log-all switch.
  */
-char last_func_long[MAX_STRING_LENGTH];
-char last_func_short[MAX_INPUT_LENGTH];
-DESCRIPTOR_DATA *last_descriptor;
 
 CH_CMD(do_null)
 {
@@ -56,6 +45,11 @@
 	return;
 }
 
+bool cmd_level_ok(CHAR_DATA * ch, CMD_DATA * cmd)
+{
+	return (get_trust(ch) >= cmd->level);
+}
+
 /*
  * The main entry point for executing commands.
  * Can be recursively called from 'at', 'order', 'force'.
@@ -65,15 +59,13 @@
 	char command[MAX_INPUT_LENGTH];
 	char logline[MAX_INPUT_LENGTH];
 	CMD_DATA *cmd;
-	int trust;
-	bool found;
 
 	/*
 	 * Strip leading spaces.
 	 */
 	while (isspace(*argument))
 		argument++;
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 		return;
 
 	/*
@@ -90,17 +82,21 @@
 		return;
 	}
 
+	strcpy(logline, argument);
+	crash_info.desc = ch->desc;
+	strcpy(crash_info.shrt_cmd, logline);
+	sprintf(crash_info.long_cmd, "[%5ld] %s in [%5ld] %s: %s",
+			IS_NPC(ch) ? ch->pIndexData->vnum : 0, IS_NPC(ch) ?
+			ch->short_descr : ch->name, ch->in_room ?
+			ch->in_room->vnum : 0, ch->in_room ? ch->in_room->name :
+			"(not in a room)", logline);
+	crash_info.cmd_status = 2;
+
 	/*
 	 * Grab the command word.
 	 * Special parsing so ' can be a command,
 	 *   also no spaces needed after punctuation.
 	 */
-	strcpy(logline, argument);
-
-	update_last_func(ch->desc, FORMATF("%s in room[%ld]: %s.", ch->name,
-									   ch->in_room ? ch->in_room->vnum : 0,
-									   argument), argument);
-
 	if (!isalpha(argument[0]) && !isdigit(argument[0]))
 	{
 		command[0] = argument[0];
@@ -117,27 +113,22 @@
 	/*
 	 * Look for command in command table.
 	 */
-	found = FALSE;
-	trust = get_trust(ch);
 	for (cmd = command_hash[LOWER(command[0]) % 126]; cmd; cmd = cmd->next_hash)
 	{
-		if (!str_prefix(command, cmd->name) && cmd->level <= trust)
-		{
-			found = TRUE;
+		if (!str_prefix(command, cmd->name) && cmd_level_ok(ch, cmd))
 			break;
-		}
 	}
 
 	/*
 	 * Log and snoop.
 	 */
-	if (found)
+	if (cmd)
 	{
 		if (cmd->log == LOG_NEVER)
 			strcpy(logline, "");
 
-		if ((!IS_NPC(ch) && IS_SET(ch->act, PLR_LOG)) || fLogAll ||
-			cmd->log == LOG_ALWAYS)
+		if ((!IS_NPC(ch) && IS_SET(ch->act, PLR_LOG))
+			|| IS_SET(mud_info.mud_flags, MUD_LOGALL) || cmd->log == LOG_ALWAYS)
 		{
 			sprintf(log_buf, "Log %s: %s", ch->name, logline);
 			wiznet(log_buf, ch, NULL, WIZ_SECURE, 0, get_trust(ch));
@@ -148,11 +139,10 @@
 
 	if (ch->desc != NULL && ch->desc->snoop_by != NULL)
 	{
-		write_to_buffer(ch->desc->snoop_by, "% ", 2);
-		write_to_buffer(ch->desc->snoop_by, logline, 0);
-		write_to_buffer(ch->desc->snoop_by, "\n\r", 2);
+		d_print(ch->desc->snoop_by, "% ", 2);
+		d_println(ch->desc->snoop_by, logline, 0);
 	}
-	if (!found)
+	if (!cmd)
 	{
 		/*
 		 * Look for command in socials table.
@@ -161,7 +151,7 @@
 			chprintln(ch, "Huh?");
 		return;
 	}
-	else if (check_disabled(cmd))
+	else if (check_disabled(ch, cmd))
 	{
 		chprintln(ch, "This command has been temporarily disabled.");
 		return;
@@ -203,19 +193,26 @@
 			chprintln(ch, "No way!  You are still fighting!");
 			break;
 
+		default:
+			break;
 		}
 		return;
 	}
 
+	crash_info.cmd_status = 1;
+
 	/*
 	 * Dispatch the command.
 	 */
 	(*cmd->do_fun) (ch, argument);
 
-	update_last_func(ch->desc,
-					 FORMATF("(Finished) %s in room[%ld]: %s.", ch->name,
-							 ch->in_room ? ch->in_room->vnum : 0, cmd->name),
-					 FORMATF("(Finished) %s", cmd->name));
+	crash_info.cmd_status = 3;
+
+	strcat(crash_info.shrt_cmd, " (Finished)");
+	strcat(crash_info.long_cmd, " (Finished)");
+
+	crash_info.cmd_status = 0;
+
 	tail_chain();
 	return;
 }
@@ -292,12 +289,13 @@
 			break;
 		chprintln(ch, "In your dreams, or what?");
 		return TRUE;
-
+	default:
+		break;
 	}
 
 	one_argument(argument, arg);
 	victim = NULL;
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		act(cmd->others_no_arg, ch, NULL, victim, TO_ROOM);
 		act(cmd->char_no_arg, ch, NULL, victim, TO_CHAR);
@@ -313,6 +311,11 @@
 	}
 	else
 	{
+		if (is_ignoring(victim, ch->name, IGNORE_SOCIALS))
+		{
+			act("$N is ignoring socials from you.", ch, NULL, victim, TO_CHAR);
+			return TRUE;
+		}
 		act(cmd->others_found, ch, NULL, victim, TO_NOTVICT);
 		act(cmd->char_found, ch, NULL, victim, TO_CHAR);
 		act(cmd->vict_found, ch, NULL, victim, TO_VICT);
@@ -456,7 +459,7 @@
 	col = 0;
 	for (cmd = cmd_first_sorted; cmd; cmd = cmd->next_sort)
 	{
-		if (cmd->level < LEVEL_HERO && cmd->level <= get_trust(ch) && cmd->show)
+		if (cmd->level < LEVEL_HERO && cmd_level_ok(ch, cmd) && cmd->show)
 		{
 			chprintf(ch, "%-12s", cmd->name);
 			if (++col % 6 == 0)
@@ -478,8 +481,7 @@
 	col = 0;
 	for (cmd = cmd_first_sorted; cmd; cmd = cmd->next_sort)
 	{
-		if (cmd->level >= LEVEL_HERO &&
-			cmd->level <= get_trust(ch) && cmd->show)
+		if (cmd->level >= LEVEL_HERO && cmd_level_ok(ch, cmd) && cmd->show)
 		{
 			chprintf(ch, "%-12s", cmd->name);
 			if (++col % 6 == 0)
@@ -502,6 +504,7 @@
 {
 	CMD_DATA *i;
 	DISABLED_DATA *p;
+	char arg[MIL];
 
 	if (IS_NPC(ch))
 	{
@@ -509,7 +512,9 @@
 		return;
 	}
 
-	if (!argument[0])			/* Nothing specified. Show disabled commands. */
+	argument = one_argument(argument, arg);
+
+	if (IS_NULLSTR(arg))		/* Nothing specified. Show disabled commands. */
 	{
 		if (!disabled_first)	/* Any disabled at all ? */
 		{
@@ -518,12 +523,12 @@
 		}
 
 		chprintln(ch, "Disabled commands:\n\r"
-				  "Command      Level   Disabled by");
+				  "Command      Level   Disabled by   Disabled for");
 
 		for (p = disabled_first; p; p = p->next)
 		{
-			chprintlnf(ch, "%-12s %5d   %-12s", p->command->name,
-					   p->level, p->disabled_by);
+			chprintlnf(ch, "%-12s %5d   %-12s  %s", p->command->name,
+					   p->level, p->disabled_by, p->disabled_for);
 		}
 		return;
 	}
@@ -532,7 +537,7 @@
 
 	/* First check if it is one of the disabled commands */
 	for (p = disabled_first; p; p = p->next)
-		if (!str_cmp(argument, p->command->name))
+		if (!str_cmp(arg, p->command->name))
 			break;
 
 	if (p)						/* this command is disabled */
@@ -549,24 +554,18 @@
 		/* Remove */
 		UNLINK(p, disabled_first, disabled_last, next, prev);
 		free_string(p->disabled_by);	/* free name of disabler */
+		free_string(p->disabled_for);
 		free_mem(p);			/* free node */
 		save_disabled();		/* save to disk */
 		chprintln(ch, "Command enabled.");
 	}
 	else						/* not a disabled command, check if that command exists */
 	{
-		/* IQ test */
-		if (!str_cmp(argument, "disable"))
-		{
-			chprintln(ch, "You cannot disable the disable command.");
-			return;
-		}
 
 		/* Search for the command */
 		for (i = command_hash[LOWER(argument[0]) % 126]; i; i = i->next_hash)
 			if (!str_cmp(i->name, argument))
 				break;
-
 		/* Found? */
 		if (!i)
 		{
@@ -574,6 +573,13 @@
 			return;
 		}
 
+		/* IQ test */
+		if (i->do_fun == do_disable)
+		{
+			chprintln(ch, "You cannot disable the disable command.");
+			return;
+		}
+
 		/* Can the imm use this command at all ? */
 		if (i->level > get_trust(ch))
 		{
@@ -587,6 +593,7 @@
 
 		p->command = i;
 		p->disabled_by = str_dup(ch->name);	/* save name of disabler */
+		p->disabled_for = str_dup(argument);
 		p->level = get_trust(ch);	/* save trust */
 		LINK(p, disabled_first, disabled_last, next, prev);
 
@@ -599,33 +606,39 @@
    Note that we check for equivalence of the do_fun pointers; this means
    that disabling 'chat' will also disable the '.' command
 */
-bool check_disabled(const struct cmd_type * command)
+bool check_disabled(CHAR_DATA * ch, CMD_DATA * command)
 {
 	DISABLED_DATA *p;
 
 	for (p = disabled_first; p; p = p->next)
 		if (p->command->do_fun == command->do_fun)
-			return TRUE;
+			break;
+
+	if (!p)
+		return FALSE;
+
+	if (!ch || IS_NULLSTR(p->disabled_for))
+		return TRUE;
 
-	return FALSE;
+	return is_exact_name(ch->name, p->disabled_for);
 }
 
 /* Load disabled commands */
 void load_disabled()
 {
-	FILE *fp;
+	READ_DATA *fp;
 	DISABLED_DATA *p;
 	char *name;
 	CMD_DATA *i;
 
 	disabled_first = NULL;
 
-	fp = file_open(DISABLED_FILE, "r");
+	fp = open_read(DISABLED_FILE);
 
 	if (!fp)					/* No disabled file.. no disabled commands : */
 		return;
 
-	name = fread_word(fp);
+	name = read_word(fp);
 
 	while (str_cmp(name, END_MARKER))	/* as long as name is NOT END_MARKER :) */
 	{
@@ -636,29 +649,29 @@
 
 		if (!i)					/* command does not exist? */
 		{
-			bug("Skipping uknown command in " DISABLED_FILE " file.", 0);
-			fread_number(fp);	/* level */
-			fread_word(fp);		/* disabled_by */
+			bug("Skipping uknown command in " DISABLED_FILE " file.");
+			read_to_eol(fp);
 		}
 		else					/* add new disabled command */
 		{
 			alloc_mem(p, DISABLED_DATA, 1);
 			p->command = i;
-			p->level = fread_number(fp);
-			p->disabled_by = str_dup(fread_word(fp));
+			p->level = read_number(fp);
+			p->disabled_by = str_dup(read_word(fp));
+			p->disabled_for = read_string(fp);
 			LINK(p, disabled_first, disabled_last, next, prev);
 		}
 
-		name = fread_word(fp);
+		name = read_word(fp);
 	}
 
-	file_close(fp);
+	close_read(fp);
 }
 
 /* Save disabled commands */
 void save_disabled()
 {
-	FILE_DATA *fp;
+	WRITE_DATA *fp;
 	DISABLED_DATA *p;
 
 	if (!disabled_first)		/* delete file if no commands are disabled */
@@ -667,19 +680,19 @@
 		return;
 	}
 
-	fp = fopen_temp(DISABLED_FILE);
+	fp = open_write(DISABLED_FILE);
 
 	if (!fp)
 	{
-		bug("Could not open " DISABLED_FILE " for writing", 0);
+		bug("Could not open " DISABLED_FILE " for writing");
 		return;
 	}
 
 	for (p = disabled_first; p; p = p->next)
-		fprintf(fp->file, "%s %d %s\n", p->command->name, p->level,
-				p->disabled_by);
+		fprintf(fp->stream, "'%s' %d '%s' %s~\n", p->command->name, p->level,
+				p->disabled_by, p->disabled_for);
 
-	fprintf(fp->file, "%s\n", END_MARKER);
+	fprintf(fp->stream, "%s\n", END_MARKER);
 
-	fclose_temp(fp);
+	close_write(fp);
 }
diff -ur -x config -x o -x rom src/interp.h new/interp.h
--- src/interp.h	Tue May 27 02:46:36 2003
+++ new/interp.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
@@ -31,13 +31,8 @@
 #define INTERP_H
 
 /* wrapper function for safe command execution */
-void do_function args((CHAR_DATA * ch, DO_FUN * do_fun, const char *argument));
-
-extern char last_func_long[MAX_STRING_LENGTH];
-extern char last_func_short[MAX_INPUT_LENGTH];
-extern DESCRIPTOR_DATA *last_descriptor;
-void update_last_func
-args((DESCRIPTOR_DATA * d, const char *lstr, const char *sstr));
+PROTOTYPE(void do_function,
+		  (CHAR_DATA * ch, DO_FUN * do_fun, const char *argument));
 
 /* for command types */
 #define ML 	MAX_LEVEL			/* implementor */
@@ -75,7 +70,7 @@
 	DO_FUN *fun;
 };
 
-extern const struct dofun_type dofun_table[];
+EXTERN const struct dofun_type dofun_table[];
 
 /*
  * Command logging types.
@@ -88,7 +83,6 @@
  * Command functions.
  * Defined in act_*.c (mostly).
  */
-#include "dofun.h"
 DECLARE_DO_FUN(do_null);
 DECLARE_DO_FUN(do_oldhelp);
 DECLARE_DO_FUN(do_mstat);
@@ -96,13 +90,13 @@
 DECLARE_DO_FUN(do_sset);
 DECLARE_DO_FUN(do_mfind);
 DECLARE_DO_FUN(do_ofind);
-DECLARE_DO_FUN(do_rset);
 DECLARE_DO_FUN(do_mload);
 DECLARE_DO_FUN(do_oload);
 DECLARE_DO_FUN(do_rstat);
-DECLARE_DO_FUN(do_mset);
-DECLARE_DO_FUN(do_oset);
 DECLARE_DO_FUN(do_slookup);
 DECLARE_DO_FUN(do_ncheck);
+DECLARE_DO_FUN(do_old_stat);
+
+#include "dofun.h"
 
 #endif
diff -ur -x config -x o -x rom src/lookup.c new/lookup.c
--- src/lookup.c	Tue May 27 02:46:36 2003
+++ new/lookup.c	Sun Aug 31 19:23:20 2003
@@ -22,14 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
 #include "merc.h"
 #include "tables.h"
 #include "olc.h"
@@ -64,7 +60,7 @@
 	return NULL;
 }
 
-int position_lookup(const char *name)
+position_t position_lookup(const char *name)
 {
 	int pos;
 
@@ -72,10 +68,10 @@
 	{
 		if (LOWER(name[0]) == LOWER(position_table[pos].name[0]) &&
 			!str_prefix(name, position_table[pos].name))
-			return pos;
+			return (position_t) pos;
 	}
 
-	return -1;
+	return POS_NONE;
 }
 
 int sex_lookup(const char *name)
@@ -156,10 +152,10 @@
 
 	argall[0] = '\0';
 
-	while (keyword[0] != '\0')
+	while (!IS_NULLSTR(keyword))
 	{
 		keyword = one_argument(keyword, temp);
-		if (argall[0] != '\0')
+		if (!IS_NULLSTR(argall))
 			strcat(argall, " ");
 		strcat(argall, temp);
 	}
diff -ur -x config -x o -x rom src/lookup.h new/lookup.h
--- src/lookup.h	Tue May 27 02:46:36 2003
+++ new/lookup.h	Sun Aug 31 19:23:21 2003
@@ -22,19 +22,20 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
 #if !defined(LOOKUP_H)
 #define LOOKUP_H
 
-CLAN_DATA *clan_lookup args((const char *name));
-int position_lookup args((const char *name));
-int sex_lookup args((const char *name));
-int size_lookup args((const char *name));
-HELP_DATA *help_lookup args((const char *));
-DEITY_DATA *deity_lookup args((const char *arg));
-int tzone_lookup args((const char *arg));
+PROTOTYPE(CLAN_DATA * clan_lookup, (const char *));
+PROTOTYPE(position_t position_lookup, (const char *));
+PROTOTYPE(int sex_lookup, (const char *));
+PROTOTYPE(int size_lookup, (const char *));
+PROTOTYPE(HELP_DATA * help_lookup, (const char *));
+PROTOTYPE(DEITY_DATA * deity_lookup, (const char *));
+PROTOTYPE(int tzone_lookup, (const char *));
+PROTOTYPE(int song_lookup, (const char *));
 
 #endif
Only in new: macro.h
diff -ur -x config -x o -x rom src/magic.c new/magic.c
--- src/magic.c	Tue May 27 02:46:36 2003
+++ new/magic.c	Sun Aug 31 19:23:20 2003
@@ -22,15 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "magic.h"
@@ -41,10 +36,10 @@
 /*
  * Local functions.
  */
-void say_spell args((CHAR_DATA * ch, int sn));
+PROTOTYPE(void say_spell, (CHAR_DATA *, int));
 
 /* imported functions */
-bool remove_obj args((CHAR_DATA * ch, int iWear, bool fReplace));
+PROTOTYPE(bool remove_obj, (CHAR_DATA *, wloc_t, bool));
 
 /*
  * Lookup a skill by name.
@@ -277,7 +272,7 @@
 	target_name = one_argument(argument, arg1);
 	one_argument(target_name, arg2);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		chprintln(ch, "Cast which what where?");
 		return;
@@ -317,14 +312,14 @@
 	switch (skill_table[sn].target)
 	{
 	default:
-		bug("Do_cast: bad target for sn %d.", sn);
+		bugf("Do_cast: bad target for sn %d.", sn);
 		return;
 
 	case TAR_IGNORE:
 		break;
 
 	case TAR_CHAR_OFFENSIVE:
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			if ((victim = ch->fighting) == NULL)
 			{
@@ -370,7 +365,7 @@
 		break;
 
 	case TAR_CHAR_DEFENSIVE:
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			victim = ch;
 		}
@@ -388,7 +383,7 @@
 		break;
 
 	case TAR_CHAR_SELF:
-		if (arg2[0] != '\0' && !is_name(target_name, ch->name))
+		if (!IS_NULLSTR(arg2) && !is_name(target_name, ch->name))
 		{
 			chprintln(ch, "You cannot cast this spell on another.");
 			return;
@@ -399,7 +394,7 @@
 		break;
 
 	case TAR_OBJ_INV:
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			chprintln(ch, "What should the spell be cast upon?");
 			return;
@@ -416,7 +411,7 @@
 		break;
 
 	case TAR_OBJ_CHAR_OFF:
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			if ((victim = ch->fighting) == NULL)
 			{
@@ -463,7 +458,7 @@
 		break;
 
 	case TAR_OBJ_CHAR_DEF:
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			vo = (void *) ch;
 			target = TARGET_CHAR;
@@ -551,14 +546,14 @@
 
 	if (sn >= maxSkill || skill_table[sn].spell_fun == 0)
 	{
-		bug("Obj_cast_spell: bad sn %d.", sn);
+		bugf("Obj_cast_spell: bad sn %d.", sn);
 		return;
 	}
 
 	switch (skill_table[sn].target)
 	{
 	default:
-		bug("Obj_cast_spell: bad target for sn %d.", sn);
+		bugf("Obj_cast_spell: bad target for sn %d.", sn);
 		return;
 
 	case TAR_IGNORE:
@@ -854,7 +849,7 @@
 		return;
 	}
 
-	if (weather_info.sky < SKY_RAINING)
+	if (ch->in_room->area->weather.precip <= 0)
 	{
 		chprintln(ch, "You need bad weather.");
 		return;
@@ -1283,7 +1278,7 @@
 	af.type = sn;
 	af.level = level;
 	af.duration = number_fuzzy(level / 4);
-	af.location = 0;
+	af.location = APPLY_NONE;
 	af.modifier = 0;
 	af.bitvector = AFF_CHARM;
 	affect_to_char(victim, &af);
@@ -1361,7 +1356,7 @@
 {
 	OBJ_DATA *light;
 
-	if (target_name[0] != '\0')	/* do a glow on some object */
+	if (!IS_NULLSTR(target_name))	/* do a glow on some object */
 	{
 		light = get_obj_carry(ch, target_name, ch);
 
@@ -1391,14 +1386,41 @@
 
 MAGIC(spell_control_weather)
 {
-	if (!str_cmp(target_name, "better"))
-		weather_info.change += dice(level / 3, 4);
-	else if (!str_cmp(target_name, "worse"))
-		weather_info.change -= dice(level / 3, 4);
+	WEATHER_DATA *weath;
+	int change;
+
+	weath = &ch->in_room->area->weather;
+
+	change = number_range(-mud_info.rand_factor, mud_info.rand_factor) +
+		(ch->level * 3) / (2 * mud_info.max_vector);
+
+	if (!str_cmp(target_name, "warmer"))
+		weath->temp_vector += change;
+	else if (!str_cmp(target_name, "colder"))
+		weath->temp_vector -= change;
+	else if (!str_cmp(target_name, "wetter"))
+		weath->precip_vector += change;
+	else if (!str_cmp(target_name, "drier"))
+		weath->precip_vector -= change;
+	else if (!str_cmp(target_name, "windier"))
+		weath->wind_vector += change;
+	else if (!str_cmp(target_name, "calmer"))
+		weath->wind_vector -= change;
 	else
-		chprintln(ch, "Do you want it to get better or worse?");
+	{
+		chprintln(ch, "Do you want it to get warmer, colder, wetter, "
+				  "drier, windier, or calmer?");
+		return;
+	}
 
-	chprintln(ch, "Ok.");
+	weath->temp_vector = URANGE(-mud_info.max_vector,
+								weath->temp_vector, mud_info.max_vector);
+	weath->precip_vector = URANGE(-mud_info.max_vector,
+								  weath->precip_vector, mud_info.max_vector);
+	weath->wind_vector = URANGE(-mud_info.max_vector,
+								weath->wind_vector, mud_info.max_vector);
+
+	chprintln(ch, "The weather is altered by your magic.");
 	return;
 }
 
@@ -1441,6 +1463,7 @@
 {
 	OBJ_DATA *obj = (OBJ_DATA *) vo;
 	int water;
+	WEATHER_DATA *weath;
 
 	if (obj->item_type != ITEM_DRINK_CON)
 	{
@@ -1454,9 +1477,9 @@
 		return;
 	}
 
-	water =
-		UMIN(level * (weather_info.sky >= SKY_RAINING ? 4 : 2),
-			 obj->value[0] - obj->value[1]);
+	weath = &ch->in_room->area->weather;
+
+	water = UMIN(level * (weath >= 0 ? 4 : 2), obj->value[0] - obj->value[1]);
 
 	if (water > 0)
 	{
@@ -1467,8 +1490,7 @@
 			char buf[MAX_STRING_LENGTH];
 
 			sprintf(buf, "%s water", obj->name);
-			free_string(obj->name);
-			obj->name = str_dup(buf);
+			replace_string(obj->name, buf);
 		}
 		act("$p is filled.", ch, obj, NULL, TO_CHAR);
 	}
@@ -2134,7 +2156,7 @@
 		return;
 	}
 
-	if (obj->wear_loc != -1)
+	if (obj->wear_loc != WEAR_NONE)
 	{
 		chprintln(ch, "The item must be carried to be enchanted.");
 		return;
@@ -2313,7 +2335,7 @@
 		return;
 	}
 
-	if (obj->wear_loc != -1)
+	if (obj->wear_loc != WEAR_NONE)
 	{
 		chprintln(ch, "The item must be carried to be enchanted.");
 		return;
@@ -2707,7 +2729,7 @@
 	af.type = sn;
 	af.level = level;
 	af.duration = level + 3;
-	af.location = 0;
+	af.location = APPLY_NONE;
 	af.modifier = 0;
 	af.bitvector = AFF_FLYING;
 	affect_to_char(victim, &af);
@@ -2951,7 +2973,7 @@
 				switch (obj_lose->item_type)
 				{
 				case ITEM_ARMOR:
-					if (obj_lose->wear_loc != -1)	/* remove the item */
+					if (obj_lose->wear_loc != WEAR_NONE)	/* remove the item */
 					{
 						if (can_drop_obj
 							(victim, obj_lose)
@@ -3004,7 +3026,7 @@
 					}
 					break;
 				case ITEM_WEAPON:
-					if (obj_lose->wear_loc != -1)	/* try to drop it */
+					if (obj_lose->wear_loc != WEAR_NONE)	/* try to drop it */
 					{
 						if (IS_WEAPON_STAT(obj_lose, WEAPON_FLAMING))
 							continue;
@@ -3501,7 +3523,6 @@
 
 MAGIC(spell_locate_object)
 {
-	char buf[MAX_INPUT_LENGTH];
 	BUFFER *buffer;
 	OBJ_DATA *obj;
 	OBJ_DATA *in_obj;
@@ -3529,23 +3550,20 @@
 
 		if (in_obj->carried_by != NULL && can_see(ch, in_obj->carried_by))
 		{
-			sprintf(buf, "one is carried by %s\n\r",
-					PERS(in_obj->carried_by, ch));
+			bprintlnf(buffer, "one is carried by %s",
+					  PERS(in_obj->carried_by, ch));
 		}
 		else
 		{
 			if (IS_IMMORTAL(ch) && in_obj->in_room != NULL)
-				sprintf(buf, "one is in %s [Room %ld]\n\r",
-						in_obj->in_room->name, in_obj->in_room->vnum);
+				bprintlnf(buffer, "one is in %s [Room %ld]",
+						  in_obj->in_room->name, in_obj->in_room->vnum);
 			else
-				sprintf(buf, "one is in %s\n\r",
-						in_obj->in_room ==
-						NULL ? "somewhere" : in_obj->in_room->name);
+				bprintlnf(buffer, "one is in %s",
+						  in_obj->in_room ==
+						  NULL ? "somewhere" : in_obj->in_room->name);
 		}
 
-		buf[0] = UPPER(buf[0]);
-		add_buf(buffer, buf);
-
 		if (number >= max_found)
 			break;
 	}
@@ -3553,7 +3571,7 @@
 	if (!found)
 		chprintln(ch, "Nothing like that in heaven or earth.");
 	else
-		page_to_char(buf_string(buffer), ch);
+		sendpage(ch, buf_string(buffer));
 
 	free_buf(buffer);
 
@@ -3740,7 +3758,7 @@
 			af.type = sn;
 			af.level = level / 2;
 			af.duration = level / 8;
-			af.location = 0;
+			af.location = APPLY_NONE;
 			af.modifier = 0;
 			af.bitvector = WEAPON_POISON;
 			affect_to_obj(obj, &af);
diff -ur -x config -x o -x rom src/magic.h new/magic.h
--- src/magic.h	Tue May 27 02:46:36 2003
+++ new/magic.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
diff -ur -x config -x o -x rom src/magic2.c new/magic2.c
--- src/magic2.c	Tue May 27 02:46:36 2003
+++ new/magic2.c	Sun Aug 31 19:23:20 2003
@@ -22,20 +22,15 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "magic.h"
 
-extern char *target_name;
+EXTERN char *target_name;
 
 MAGIC(spell_farsight)
 {
diff -ur -x config -x o -x rom src/mccp.c new/mccp.c
--- src/mccp.c	Tue May 27 02:46:36 2003
+++ new/mccp.c	Sun Aug 31 19:23:20 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /*
@@ -36,29 +36,19 @@
  * retained intact.
  */
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-
 #include "merc.h"
 #include "telnet.h"
-#if defined(WIN32)
-#include "../win32/winstuff.h"
-#endif
 
 #if !defined(NO_MCCP)
 
-char compress_start[] = { IAC, SB, TELOPT_COMPRESS, WILL, SE, '\0' };
+char compress2_start[] = { IAC, SB, TELOPT_COMPRESS2, IAC, SE, NUL };
+char compress1_start[] = { IAC, SB, TELOPT_COMPRESS, IAC, SE, NUL };
+
+PROTOTYPE(bool processCompressed, (DESCRIPTOR_DATA *));
 
-bool processCompressed(DESCRIPTOR_DATA * desc);
+#if defined(__FreeBSD__) && !defined(ENOSR)
+#define ENOSR 63
+#endif
 
 /*
  * Memory management - zlib uses these hooks to allocate and free memory
@@ -78,7 +68,7 @@
 /*
  * Begin compressing data on `desc'
  */
-bool compressStart(DESCRIPTOR_DATA * desc)
+bool compressStart(DESCRIPTOR_DATA * desc, int version)
 {
 	z_stream *s;
 
@@ -107,21 +97,34 @@
 		return FALSE;
 	}
 
-	write_to_descriptor(desc, compress_start, strlen(compress_start));
-
+	switch (version)
+	{
+	default:
+	case 1:
+		desc->mccp_version = 1;
+		d_write(desc, compress1_start, 0);
+		break;
+	case 2:
+		desc->mccp_version = 2;
+		d_write(desc, compress2_start, 0);
+		break;
+	}
 	/* now we're compressing */
 	desc->out_compress = s;
 	return TRUE;
 }
 
 /* Cleanly shut down compression on `desc' */
-bool compressEnd(DESCRIPTOR_DATA * desc)
+bool compressEnd(DESCRIPTOR_DATA * desc, int version)
 {
 	unsigned char dummy[1];
 
 	if (!desc->out_compress)
 		return TRUE;
 
+	if (desc->mccp_version != version)
+		return TRUE;
+
 	desc->out_compress->avail_in = 0;
 	desc->out_compress->next_in = dummy;
 
@@ -155,6 +158,7 @@
 	if (len > 0)
 	{
 		/* we have some data to write */
+		desc->bytes_compressed += len;
 
 		for (iStart = 0; iStart < len; iStart += nWrite)
 		{
@@ -192,8 +196,8 @@
 	return TRUE;
 }
 
-/* write_to_descriptor, the compressed case */
-bool writeCompressed(DESCRIPTOR_DATA * desc, char *txt, int length)
+/* d_write, the compressed case */
+bool writeCompressed(DESCRIPTOR_DATA * desc, const char *txt, int length)
 {
 	z_stream *s = desc->out_compress;
 
@@ -241,25 +245,57 @@
 		return;
 	}
 
-	if (!ch->desc->out_compress)
+	if (IS_NULLSTR(argument))
 	{
-		if (!compressStart(ch->desc))
+		if (ch->desc->out_compress)
 		{
-			chprint(ch, "Failed.\n");
-			return;
+			double bcomp = ch->desc->bytes_compressed;
+			double bnorm = ch->desc->bytes_normal;
+			double percent = 100 - ((bcomp / bnorm) * 100);
+
+			chprintlnf(ch, "Bytes Normal    : %ld", ch->desc->bytes_normal);
+			chprintlnf(ch, "Bytes Compressed: %ld", ch->desc->bytes_compressed);
+			chprintlnf(ch, "MCCP version    : %d", ch->desc->mccp_version);
+			chprintlnf(ch, "Compression Rate: %2.2f%%", percent);
+		}
+		else
+		{
+			chprintlnf(ch, "Bytes Normal    : %ld", ch->desc->bytes_normal);
+			chprintln(ch, "You are not compressing data.");
 		}
+		chprintln(ch, "Syntax: compress  on/off");
+		return;
+	}
 
-		chprintln(ch, "Ok, compression enabled.");
+	if (!str_cmp(argument, "on"))
+	{
+		if (!ch->desc->out_compress)
+		{
+			chprintln(ch,
+					  "NOTE: If you did not have compression running after logging\n\r"
+					  "      in, chances are your client does not support it and you\n\r"
+					  "      will recieve strange output...");
+			if (!compressStart(ch->desc, ch->desc->mccp_version))
+			{
+				chprint(ch, "Failed.\n");
+				return;
+			}
+			chprintln(ch, "Ok, compression enabled.");
+		}
+		else
+			chprintln(ch, "You already have compression enabled.");
+		return;
 	}
-	else
+	if (!str_cmp(argument, "off"))
 	{
-		if (!compressEnd(ch->desc))
+		if (!compressEnd(ch->desc, ch->desc->mccp_version))
 		{
 			chprint(ch, "Failed.\n");
 			return;
 		}
 
 		chprint(ch, "Ok, compression disabled.\n");
+		return;
 	}
 #endif
 }
diff -ur -x config -x o -x rom src/mem.c new/mem.c
--- src/mem.c	Tue May 27 02:46:36 2003
+++ new/mem.c	Sun Aug 31 19:23:20 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /***************************************************************************
@@ -38,12 +38,6 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "recycle.h"
 #include "olc.h"
@@ -100,6 +94,17 @@
 	pArea->version = 0;
 	pArea->min_vnum = 0;
 	pArea->max_vnum = 0;
+	pArea->weather.temp = 0;
+	pArea->weather.precip = 0;
+	pArea->weather.wind = 0;
+	pArea->weather.temp_vector = 0;
+	pArea->weather.precip_vector = 0;
+	pArea->weather.wind_vector = 0;
+	pArea->weather.climate_temp = 2;
+	pArea->weather.climate_precip = 2;
+	pArea->weather.climate_wind = 2;
+	pArea->weather.echo = &str_empty[0];
+	pArea->weather.echo_color = &str_empty[0];
 	pArea->age = 32;			/* 32 so areas reset on boot */
 	pArea->nplayer = 0;
 	pArea->vnum = top_area;
@@ -170,7 +175,7 @@
 	pRoom->vnum = 0;
 	pRoom->room_flags = 0;
 	pRoom->light = 0;
-	pRoom->sector_type = 0;
+	pRoom->sector_type = SECT_NONE;
 	pRoom->clan = NULL;
 	pRoom->heal_rate = 100;
 	pRoom->mana_rate = 100;
@@ -213,7 +218,7 @@
 	return;
 }
 
-extern AFFECT_DATA *affect_free;
+EXTERN AFFECT_DATA *affect_free;
 
 SHOP_DATA *new_shop(void)
 {
@@ -324,7 +329,7 @@
 	pMob->affected_by = 0;
 	pMob->alignment = 0;
 	pMob->hitroll = 0;
-	pMob->race = race_lookup("human");	/* - Hugin */
+	pMob->race = default_race;	/* - Hugin */
 	pMob->form = 0;				/* ROM patch -- Hugin */
 	pMob->parts = 0;			/* ROM patch -- Hugin */
 	pMob->imm_flags = 0;		/* ROM patch -- Hugin */
@@ -385,6 +390,7 @@
 	NewCode->vnum = 0;
 	NewCode->code = str_dup("");
 	NewCode->next = NULL;
+	NewCode->area = NULL;
 
 	return NewCode;
 }
diff -ur -x config -x o -x rom src/merc.h new/merc.h
--- src/merc.h	Tue May 27 02:46:36 2003
+++ new/merc.h	Sun Aug 31 19:23:21 2003
@@ -22,2448 +22,111 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-
 #if !defined(MERC_H)
 #define MERC_H
-
-#define args( list )			list
-#define DECLARE_DO_FUN( fun )		DO_FUN    fun
-#define DECLARE_SPEC_FUN( fun )		SPEC_FUN  fun
-#define DECLARE_SPELL_FUN( fun )	SPELL_FUN fun
-#define DECLARE_LOOKUP_FUN( fun )	LOOKUP_F  fun
-#define DECLARE_ED_FUN( fun )	ED_FUN	   fun
-#define DECLARE_VALIDATE_FUN(fun)	VALIDATE_FUN	fun
-#define DECLARE_OBJ_FUN( fun )		OBJ_FUN	  fun
-#define DECLARE_ROOM_FUN( fun )		ROOM_FUN  fun
-
-/*
- * Short scalar types.
- * Diavolo reports AIX compiler has bugs with short types.
- */
-
-#if !defined(__cplusplus)
-typedef short int bool;
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
 #endif
+#if defined(WIN32)
+#include <time.h>
+#include <io.h>
+#include <process.h>
+#include <winsock2.h>
+#include <sys\timeb.h>
+#include <direct.h>
+#include <lmcons.h>
+#include "winstuff.h"
+#else
+#if !defined(_GNU_SOURCE)
+#define _GNU_SOURCE
+#endif
+#include <unistd.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <pwd.h>
+#include <dirent.h>
+#include <limits.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
 
-#if	!defined(FALSE)
-#if defined(__cplusplus)
-#define FALSE    false
-#else
-#define FALSE	 0
+#if defined(WIN32)
+#pragma warning( disable: 4018 4244 4305 4761 4800 4309)
+#if !defined(NO_COPYOVER)
+#define NO_COPYOVER
 #endif
+#if !defined(NO_VTIMER)
+#define NO_VTIMER
 #endif
-
-#if	!defined(TRUE)
-#if defined(__cplusplus)
-#define TRUE     true
-#else
-#define TRUE	 1
+#if !defined(NOCRYPT)
+#define NOCRYPT
 #endif
+#elif defined(__CYGWIN__)
+#if !defined(NO_COPYOVER)
+#define NO_COPYOVER
 #endif
-
-#if defined(WIN32)
-#pragma warning( disable: 4018 4244 4305 4761 4800 4309)
-#define __attribute__(x)
 #if !defined(NOCRYPT)
 #define NOCRYPT
 #endif
-typedef __int64 flag_t;
-#else
-#if defined(__CYGWIN__)
-#define NOCRYPT
+#if !defined(NO_MCCP)
 #define NO_MCCP
 #endif
-typedef int64_t flag_t;
 #endif
 
-typedef long vnum_t;
-
-/* ea */
-#define MSL MAX_STRING_LENGTH
-#define MIL MAX_INPUT_LENGTH
-
-#include "ansi.h"
-
 #if !defined(NO_MCCP)
-
-#if !defined(WIN32)
-#include <zlib.h>
-#else
-#if defined(IN_WINSTUFF_C)
+#if defined(WIN32)
 #include "zlib.h"
 #else
-#include "../win32/zlib.h"
-#endif
+#include <zlib.h>
 #endif
-
 #define TELOPT_COMPRESS 85
 #define COMPRESS_BUF_SIZE 16384
-
-#endif
-
-/*
- * Structure types.
- */
-typedef struct affect_data AFFECT_DATA;
-typedef struct area_data AREA_DATA;
-typedef struct ban_data BAN_DATA;
-typedef struct buf_type BUFFER;
-typedef struct char_data CHAR_DATA;
-typedef struct descriptor_data DESCRIPTOR_DATA;
-typedef struct exit_data EXIT_DATA;
-typedef struct extra_descr_data EXTRA_DESCR_DATA;
-typedef struct help_data HELP_DATA;
-typedef struct kill_data KILL_DATA;
-typedef struct mem_data MEM_DATA;
-typedef struct mob_index_data MOB_INDEX_DATA;
-typedef struct note_data NOTE_DATA;
-typedef struct obj_data OBJ_DATA;
-typedef struct obj_index_data OBJ_INDEX_DATA;
-typedef struct pc_data PC_DATA;
-typedef struct gen_data GEN_DATA;
-typedef struct reset_data RESET_DATA;
-typedef struct room_index_data ROOM_INDEX_DATA;
-typedef struct shop_data SHOP_DATA;
-typedef struct time_info_data TIME_INFO_DATA;
-typedef struct weather_data WEATHER_DATA;
-typedef struct prog_list PROG_LIST;
-typedef struct prog_code PROG_CODE;
-typedef struct disabled_data DISABLED_DATA;
-typedef struct stat_data STAT_DATA;
-typedef struct social_type SOCIAL_DATA;
-typedef struct gquest_data GQUEST;
-typedef struct war_data WAR_DATA;
-typedef struct clan_type CLAN_DATA;
-typedef struct cmd_type CMD_DATA;
-typedef struct skill_type SKILL_DATA;
-typedef struct group_type GROUP_DATA;
-typedef struct race_type RACE_DATA;
-typedef struct class_type CLASS_DATA;
-typedef struct corpse_data CORPSE_DATA;
-typedef struct auction_data AUCTION_DATA;
-typedef struct clan_rank RANK_DATA;
-typedef struct deity_type DEITY_DATA;
-typedef struct wpwd_data WPWD_DATA;
-typedef struct mbr_data MBR_DATA;
-typedef struct file_data FILE_DATA;
-typedef struct war_list_type WAR_LIST;
-typedef struct gquest_list_type GQ_LIST;
-
-/*
- * Function types.
- */
-typedef void DO_FUN args((CHAR_DATA * ch, const char *argument));
-typedef bool SPEC_FUN args((CHAR_DATA * ch));
-typedef void SPELL_FUN
-args((int sn, int level, CHAR_DATA * ch, void *vo, int target));
-typedef int LOOKUP_F args((const char *));
-typedef bool ED_FUN
-args((const char *, CHAR_DATA *, const char *, void *, const void *));
-typedef bool VALIDATE_FUN args((CHAR_DATA * ch, const void *arg));
-typedef void OBJ_FUN args((OBJ_DATA * obj, const char *argument));
-typedef void ROOM_FUN args((ROOM_INDEX_DATA * room, const char *argument));
-
-#define	CH_CMD(name) void name(CHAR_DATA * ch, const char *argument)
-#define ED_FUN_DEC(blah)	bool blah ( const char * n_fun, CHAR_DATA *ch, const char *argument, void *arg, const void *par )
-#define VALIDATE_FUN(fun)	bool fun(CHAR_DATA *ch, const void *arg)
-
-/*
- * String and memory management parameters.
- */
-#define	MAX_KEY_HASH		 1024
-#define MAX_STRING_LENGTH	 4608
-#define MAX_INPUT_LENGTH	  256
-#define PAGELEN			   22
-#define MAX_EXPLORE_HASH     8192
-
-/*
- * Game parameters.
- * Increase the max'es if you add more of something.
- * Adjust the pulse numbers to suit yourself.
- */
-#define MAX_IN_GROUP		   15
-#define MAX_TZONE            25
-#define MAX_ALIAS		    5
-#define MAX_BUDDY           10
-#define MAX_REMORT          2	// should never be higher than maxClass
-#define MAX_MCLASS          (MAX_REMORT + 3)
-#define MAX_DAMAGE_MESSAGE	   41
-#define    MAX_RANK    6
-#define    MAX_HOUSE_ROOMS            5
-#define    MAX_VNUM                   60000
-#define MAX_LEVEL		   60
-#define LEVEL_IMMORTAL		   (MAX_LEVEL - 8)
-#define MAX_MORTAL_LEVEL	   (MAX_LEVEL - 9)
-#define LEVEL_HERO			   (MAX_MORTAL_LEVEL - MAX_REMORT)
-
-#define PULSE_PER_SECOND	    4
-#define PULSE_VIOLENCE		  ( 3 * PULSE_PER_SECOND)
-#define PULSE_MOBILE		  ( 4 * PULSE_PER_SECOND)
-#define PULSE_MUSIC		  ( 6 * PULSE_PER_SECOND)
-#define PULSE_TICK		  (45 * PULSE_PER_SECOND)
-#define PULSE_AREA		  (120 * PULSE_PER_SECOND)
-
-#define    AUCTION_LENGTH           (60 * PULSE_PER_SECOND)
-
-#define IMPLEMENTOR		  MAX_LEVEL
-#define	CREATOR			 (MAX_LEVEL - 1)
-#define SUPREME			 (MAX_LEVEL - 2)
-#define DEITY			 (MAX_LEVEL - 3)
-#define GOD				 (MAX_LEVEL - 4)
-#define IMMORTAL		 (MAX_LEVEL - 5)
-#define DEMI			 (MAX_LEVEL - 6)
-#define ANGEL			 (MAX_LEVEL - 7)
-#define AVATAR			 (MAX_LEVEL - 8)
-#define HERO			 LEVEL_HERO
-
-/*
- * Site ban structure.
- */
-
-#define BAN_SUFFIX		(BIT_A)
-#define BAN_PREFIX		(BIT_B)
-#define BAN_NEWBIES		(BIT_C)
-#define BAN_ALL			(BIT_D)
-#define BAN_PERMIT		(BIT_E)
-#define BAN_PERMANENT   (BIT_F)
-
-struct ban_data
-{
-	BAN_DATA *next;
-	BAN_DATA *prev;
-	bool valid;
-	flag_t ban_flags;
-	int level;
-	const char *name;
-};
-
-struct buf_type
-{
-	BUFFER *next;
-	BUFFER *prev;
-	bool valid;
-	int state;					/* error state of the buffer */
-	int size;					/* size in k */
-	char *string;				/* buffer's string */
-};
-
-struct auction_data
-{
-	AUCTION_DATA *next;
-	AUCTION_DATA *prev;
-	OBJ_DATA *item;
-	CHAR_DATA *owner;
-	CHAR_DATA *high_bidder;
-	int status;
-	int number;
-	unsigned long bid;
-	bool valid;
-};
-
-/*
- * Time and weather stuff.
- */
-#define SUN_DARK		    0
-#define SUN_RISE		    1
-#define SUN_LIGHT		    2
-#define SUN_SET			    3
-
-#define SKY_CLOUDLESS		    0
-#define SKY_CLOUDY		    1
-#define SKY_RAINING		    2
-#define SKY_LIGHTNING		    3
-
-struct time_info_data
-{
-	int hour;
-	int day;
-	int month;
-	int year;
-};
-
-struct weather_data
-{
-	int mmhg;
-	int change;
-	int sky;
-	int sunlight;
-};
-
-/* Bitvector defines, 52 for
-   A-Z, a-z 
-*/
-#define BIT_A        ((flag_t) 1 <<  0)
-#define BIT_B        ((flag_t) 1 <<  1)
-#define BIT_C        ((flag_t) 1 <<  2)
-#define BIT_D        ((flag_t) 1 <<  3)
-#define BIT_E        ((flag_t) 1 <<  4)
-#define BIT_F        ((flag_t) 1 <<  5)
-#define BIT_G        ((flag_t) 1 <<  6)
-#define BIT_H        ((flag_t) 1 <<  7)
-#define BIT_I        ((flag_t) 1 <<  8)
-#define BIT_J        ((flag_t) 1 <<  9)
-#define BIT_K        ((flag_t) 1 << 10)
-#define BIT_L        ((flag_t) 1 << 11)
-#define BIT_M        ((flag_t) 1 << 12)
-#define BIT_N        ((flag_t) 1 << 13)
-#define BIT_O        ((flag_t) 1 << 14)
-#define BIT_P        ((flag_t) 1 << 15)
-#define BIT_Q        ((flag_t) 1 << 16)
-#define BIT_R        ((flag_t) 1 << 17)
-#define BIT_S        ((flag_t) 1 << 18)
-#define BIT_T        ((flag_t) 1 << 19)
-#define BIT_U        ((flag_t) 1 << 20)
-#define BIT_V        ((flag_t) 1 << 21)
-#define BIT_W        ((flag_t) 1 << 22)
-#define BIT_X        ((flag_t) 1 << 23)
-#define BIT_Y        ((flag_t) 1 << 24)
-#define BIT_Z        ((flag_t) 1 << 25)
-#define BIT_a        ((flag_t) 1 << 26)
-#define BIT_b        ((flag_t) 1 << 27)
-#define BIT_c        ((flag_t) 1 << 28)
-#define BIT_d        ((flag_t) 1 << 29)
-#define BIT_e        ((flag_t) 1 << 30)
-#define BIT_f        ((flag_t) 1 << 31)
-#define BIT_Ax	     ((flag_t) 1 << 32)
-#define BIT_Bx	     ((flag_t) 1 << 33)
-#define BIT_Cx	     ((flag_t) 1 << 34)
-#define BIT_Dx	     ((flag_t) 1 << 35)
-#define BIT_Ex	     ((flag_t) 1 << 36)
-#define BIT_Fx	     ((flag_t) 1 << 37)
-#define BIT_Gx	     ((flag_t) 1 << 38)
-#define BIT_Hx	     ((flag_t) 1 << 39)
-#define BIT_Ix	     ((flag_t) 1 << 40)
-#define BIT_Jx	     ((flag_t) 1 << 41)
-#define BIT_Kx	     ((flag_t) 1 << 42)
-#define BIT_Lx	     ((flag_t) 1 << 43)
-#define BIT_Mx	     ((flag_t) 1 << 44)
-#define BIT_Nx	     ((flag_t) 1 << 45)
-#define BIT_Ox	     ((flag_t) 1 << 46)
-#define BIT_Px	     ((flag_t) 1 << 47)
-#define BIT_Qx	     ((flag_t) 1 << 48)
-#define BIT_Rx	     ((flag_t) 1 << 49)
-#define BIT_Sx	     ((flag_t) 1 << 50)
-#define BIT_Tx	     ((flag_t) 1 << 51)
-#define BIT_Ux	     ((flag_t) 1 << 52)
-#define BIT_Vx	     ((flag_t) 1 << 53)
-#define BIT_Wx	     ((flag_t) 1 << 54)
-#define BIT_Xx	     ((flag_t) 1 << 55)
-#define BIT_Yx	     ((flag_t) 1 << 56)
-#define BIT_Zx	     ((flag_t) 1 << 57)
-#define BIT_ax	     ((flag_t) 1 << 58)
-#define BIT_bx	     ((flag_t) 1 << 59)
-#define BIT_cx	     ((flag_t) 1 << 60)
-#define BIT_dx	     ((flag_t) 1 << 61)
-#define BIT_ex	     ((flag_t) 1 << 62)
-#define BIT_fx	     ((flag_t) 1 << 63)
-
-/*
- * Connected state for a channel.
- */
-#define CON_PLAYING			 0
-#define CON_GET_NAME			 1
-#define CON_GET_OLD_PASSWORD		 2
-#define CON_CONFIRM_NEW_NAME		 3
-#define CON_GET_NEW_PASSWORD		 4
-#define CON_CONFIRM_NEW_PASSWORD	 5
-#define CON_GET_NEW_RACE		 6
-#define CON_GET_NEW_SEX			 7
-#define CON_GET_NEW_CLASS		 8
-#define CON_GET_ALIGNMENT		 9
-#define CON_GET_DEITY           10
-#define CON_GET_TIMEZONE        11
-#define CON_DEFAULT_CHOICE		12
-#define CON_GEN_GROUPS			13
-#define CON_PICK_WEAPON			14
-#define CON_READ_IMOTD			15
-#define CON_READ_MOTD			16
-#define CON_BREAK_CONNECT		17
-#define CON_GET_TERM	        18
-#define CON_COPYOVER_RECOVER    19
-#define CON_NOTE_TO				20
-#define CON_NOTE_SUBJECT		21
-#define CON_NOTE_EXPIRE			22
-#define CON_NOTE_TEXT			23
-#define CON_NOTE_FINISH			24
-
-/*
- * Descriptor (channel) structure.
- */
-struct descriptor_data
-{
-	DESCRIPTOR_DATA *next;
-	DESCRIPTOR_DATA *prev;
-	DESCRIPTOR_DATA *snoop_by;
-	CHAR_DATA *character;
-	CHAR_DATA *original;
-	bool valid;
-	const char *host;
-	int descriptor;
-	int connected;
-	bool fcommand;
-	char inbuf[4 * MAX_INPUT_LENGTH];
-	char incomm[MAX_INPUT_LENGTH];
-	char inlast[MAX_INPUT_LENGTH];
-	int repeat;
-	char *outbuf;
-	int outsize;
-	int outtop;
-	const char *showstr_head;
-	const char *showstr_point;
-	void *pEdit;				/* OLC */
-	const char **pString;		/* OLC */
-	int editor;					/* OLC */
-	flag_t d_flags;
-	unsigned int scr_width;		/* screen width */
-	unsigned int scr_height;	/* screen height */
-#if !defined(NO_MCCP)
-	z_stream *out_compress;
-	unsigned char *out_compress_buf;
 #endif
-	const char *run_buf;
-	const char *run_head;
-};
-
-/* 
- * Descriptor Flags.
- */
-
-#define DESC_COLOUR		    (BIT_A)
-#define DESC_TELOPT_EOR		(BIT_B)
-#define DESC_TELOPT_ECHO	(BIT_C)
-#define DESC_TELOPT_NAWS	(BIT_D)
-
-/*
- * Attribute bonus structures.
- */
-struct str_app_type
-{
-	int tohit;
-	int todam;
-	int carry;
-	int wield;
-};
-
-struct int_app_type
-{
-	int learn;
-};
-
-struct wis_app_type
-{
-	int practice;
-};
-
-struct dex_app_type
-{
-	int defensive;
-};
-
-struct con_app_type
-{
-	int hitp;
-	int shock;
-};
-
-/*
- * TO types for act.
- */
-#define TO_ROOM		    BIT_A
-#define TO_NOTVICT	    BIT_B
-#define TO_VICT		    BIT_C
-#define TO_CHAR		    BIT_D
-#define TO_ALL		    BIT_E
-#define TO_DAMAGE       BIT_F
-#define TO_ZONE         BIT_G
-
-enum special_flags
-{
-	spec_public_flag,
-	spec_clan_flag,
-	spec_buddy_flag,
-	spec_imm_flag
-};
-
-/*
- * Help table types.
- */
-struct help_data
-{
-	HELP_DATA *next;
-	HELP_DATA *prev;
-	int level;
-	const char *keyword;
-	const char *text;
-};
-
-/*
- * Shop types.
- */
-#define MAX_TRADE	 5
 
-struct shop_data
-{
-	SHOP_DATA *next;
-	SHOP_DATA *prev;			/* Next shop in list        */
-	vnum_t keeper;				/* Vnum of shop keeper mob  */
-	int buy_type[MAX_TRADE];	/* Item types shop will buy */
-	int profit_buy;				/* Cost multiplier for buying   */
-	int profit_sell;			/* Cost multiplier for selling  */
-	int open_hour;				/* First opening hour       */
-	int close_hour;				/* First closing hour       */
-};
-
-/*
- * Per-class stuff.
- */
-
-#define MAX_GUILD 	2
-#define MAX_STATS 	5
-#define STAT_STR 	0
-#define STAT_INT	1
-#define STAT_WIS	2
-#define STAT_DEX	3
-#define STAT_CON	4
-#define STAT_MAX    5
-
-struct class_type
-{
-	const char *name;			/* the full name of the class */
-	int attr_prime;				/* Prime attribute      */
-	vnum_t weapon;				/* First weapon         */
-	vnum_t guild[MAX_GUILD];	/* Vnum of guild rooms      */
-	int skill_adept;			/* Maximum skill level      */
-	int thac0_00;				/* Thac0 for level  0       */
-	int thac0_32;				/* Thac0 for level 32       */
-	int hp_min;					/* Min hp gained on leveling    */
-	int hp_max;					/* Max hp gained on leveling    */
-	bool fMana;					/* Class gains mana on level    */
-	const char *base_group;		/* base skills gained       */
-	const char *default_group;	/* default skills gained    */
-};
-
-struct item_type
-{
-	int type;
-	const char *name;
-};
-
-struct weapon_type
-{
-	const char *name;
-	vnum_t vnum;
-	int type;
-	int *gsn;
-};
-
-struct wiznet_type
-{
-	const char *name;
-	flag_t flag;
-	int level;
-};
-
-struct attack_type
-{
-	const char *name;			/* name */
-	const char *noun;			/* message */
-	int damage;					/* damage class */
-};
-
-struct deity_type
-{
-	const char *name;
-	const char *desc;
-	const char *skillname;
-	DEITY_DATA *next, *prev;
-	bool valid;
-};
-
-struct corpse_data
-{
-	CORPSE_DATA *next;
-	CORPSE_DATA *prev;
-	OBJ_DATA *corpse;
-};
-
-struct race_type
-{
-	const char *name;			/* call name of the race */
-	bool pc_race;				/* can be chosen by pcs */
-	flag_t act;					/* act bits for the race */
-	flag_t aff;					/* aff bits for the race */
-	flag_t off;					/* off bits for the race */
-	flag_t imm;					/* imm bits for the race */
-	flag_t res;					/* res bits for the race */
-	flag_t vuln;				/* vuln bits for the race */
-	flag_t form;				/* default form flag_t for the race */
-	flag_t parts;				/* default parts for the race */
-	int points;					/* cost in points of the race */
-	int *class_mult;			/* exp multiplier for class, * 100 */
-	const char *skills[5];		/* bonus skills for the race */
-	int stats[MAX_STATS];		/* starting stats */
-	int max_stats[MAX_STATS];	/* maximum stats */
-	int size;					/* aff bits for the race */
-	RACE_DATA *next, *prev;
-	bool valid;
-};
+#include "ansi.h"
 
-struct spec_type
-{
-	const char *name;			/* special function name */
-	SPEC_FUN *function;			/* the function */
-};
+#include "typedef.h"
 
-/*
- * Data structure for notes.
- */
-struct note_data
-{
-	NOTE_DATA *next;
-	NOTE_DATA *prev;
-	bool valid;
-	const char *sender;
-	const char *date;
-	const char *to_list;
-	const char *subject;
-	const char *text;
-	time_t date_stamp;
-	time_t expire;
-};
+#include "defines.h"
 
 #include "board.h"
 
-struct gquest_list_type
-{
-	GQ_LIST *next, *prev;
-	CHAR_DATA *ch;
-	vnum_t *gq_mobs;
-};
-
-struct gquest_data
-{
-	GQ_LIST *first, *last;
-	CHAR_DATA *last_registar;
-	vnum_t *mobs;
-	const char *who;
-	int mob_count;
-	int timer;
-	int involved;
-	int qpoints;
-	int gold;
-	int minlevel;
-	int maxlevel;
-	int running;
-};
-
-#define		GQUEST_OFF			0
-#define		GQUEST_WAITING		1
-#define		GQUEST_RUNNING		2
-
-/*
- * An affect.
- */
-struct affect_data
-{
-	AFFECT_DATA *next;
-	AFFECT_DATA *prev;
-	bool valid;
-	int where;
-	int type;
-	int level;
-	int duration;
-	int location;
-	int modifier;
-	flag_t bitvector;
-};
-
-/* where definitions */
-#define TO_AFFECTS	0
-#define TO_OBJECT	1
-#define TO_IMMUNE	2
-#define TO_RESIST	3
-#define TO_VULN		4
-#define TO_WEAPON	5
-
-/*
- * A kill structure (indexed by level).
- */
-struct kill_data
-{
-	int number;
-	int killed;
-};
-
-/***************************************************************************
- *                                                                         *
- *                   VALUES OF INTEREST TO AREA BUILDERS                   *
- *                   (Start of section ... start here)                     *
- *                                                                         *
- ***************************************************************************/
-
-/*
- * Well known mob virtual numbers.
- * Defined in #MOBILES.
- */
-#define MOB_VNUM_FIDO		   3090
-#define MOB_VNUM_CITYGUARD	   3060
-#define MOB_VNUM_VAMPIRE	   3404
-#define	MOB_VNUM_WARMASTER     17601
-#define MOB_VNUM_PATROLMAN	   2106
-#define GROUP_VNUM_TROLLS	   2100
-#define GROUP_VNUM_OGRES	   2101
-
-#define	MOB_VNUM_REGISTAR      202
-
-/*
- * ACT bits for mobs.
- * Used in #MOBILES.
- */
-#define ACT_IS_NPC		(BIT_A)	/* Auto set for mobs    */
-#define ACT_SENTINEL	    	(BIT_B)	/* Stays in one room    */
-#define ACT_SCAVENGER	      	(BIT_C)	/* Picks up objects */
-#define ACT_AGGRESSIVE		(BIT_F)	/* Attacks PC's     */
-#define ACT_STAY_AREA		(BIT_G)	/* Won't leave area */
-#define ACT_WIMPY		(BIT_H)
-#define ACT_PET			(BIT_I)	/* Auto set for pets    */
-#define ACT_TRAIN		(BIT_J)	/* Can train PC's   */
-#define ACT_PRACTICE		(BIT_K)	/* Can practice PC's    */
-#define ACT_UNDEAD		(BIT_O)
-#define ACT_CLERIC		(BIT_Q)
-#define ACT_MAGE		(BIT_R)
-#define ACT_THIEF		(BIT_S)
-#define ACT_WARRIOR		(BIT_T)
-#define ACT_NOALIGN		(BIT_U)
-#define ACT_NOPURGE		(BIT_V)
-#define ACT_OUTDOORS		(BIT_W)
-#define ACT_INDOORS		(BIT_Y)
-#define ACT_IS_HEALER		(BIT_a)
-#define ACT_GAIN		(BIT_b)
-#define ACT_UPDATE_ALWAYS	(BIT_c)
-#define ACT_IS_CHANGER		(BIT_d)
-
-/* damage classes */
-#define DAM_NONE                0
-#define DAM_BASH                1
-#define DAM_PIERCE              2
-#define DAM_SLASH               3
-#define DAM_FIRE                4
-#define DAM_COLD                5
-#define DAM_LIGHTNING           6
-#define DAM_ACID                7
-#define DAM_POISON              8
-#define DAM_NEGATIVE            9
-#define DAM_HOLY                10
-#define DAM_ENERGY              11
-#define DAM_MENTAL              12
-#define DAM_DISEASE             13
-#define DAM_DROWNING            14
-#define DAM_LIGHT		15
-#define DAM_OTHER               16
-#define DAM_HARM		17
-#define DAM_CHARM		18
-#define DAM_SOUND		19
-
-/* OFF bits for mobiles */
-#define OFF_AREA_ATTACK         (BIT_A)
-#define OFF_BACKSTAB            (BIT_B)
-#define OFF_BASH                (BIT_C)
-#define OFF_BERSERK             (BIT_D)
-#define OFF_DISARM              (BIT_E)
-#define OFF_DODGE               (BIT_F)
-#define OFF_FADE                (BIT_G)
-#define OFF_FAST                (BIT_H)
-#define OFF_KICK                (BIT_I)
-#define OFF_KICK_DIRT           (BIT_J)
-#define OFF_PARRY               (BIT_K)
-#define OFF_RESCUE              (BIT_L)
-#define OFF_TAIL                (BIT_M)
-#define OFF_TRIP                (BIT_N)
-#define OFF_CRUSH		(BIT_O)
-#define ASSIST_ALL       	(BIT_P)
-#define ASSIST_ALIGN	        (BIT_Q)
-#define ASSIST_RACE    	     	(BIT_R)
-#define ASSIST_PLAYERS      	(BIT_S)
-#define ASSIST_GUARD        	(BIT_T)
-#define ASSIST_VNUM		(BIT_U)
-
-/* return values for check_imm */
-#define IS_NORMAL		0
-#define IS_IMMUNE		1
-#define IS_RESISTANT		2
-#define IS_VULNERABLE		3
-
-/* IMM bits for mobs */
-#define IMM_SUMMON              (BIT_A)
-#define IMM_CHARM               (BIT_B)
-#define IMM_MAGIC               (BIT_C)
-#define IMM_WEAPON              (BIT_D)
-#define IMM_BASH                (BIT_E)
-#define IMM_PIERCE              (BIT_F)
-#define IMM_SLASH               (BIT_G)
-#define IMM_FIRE                (BIT_H)
-#define IMM_COLD                (BIT_I)
-#define IMM_LIGHTNING           (BIT_J)
-#define IMM_ACID                (BIT_K)
-#define IMM_POISON              (BIT_L)
-#define IMM_NEGATIVE            (BIT_M)
-#define IMM_HOLY                (BIT_N)
-#define IMM_ENERGY              (BIT_O)
-#define IMM_MENTAL              (BIT_P)
-#define IMM_DISEASE             (BIT_Q)
-#define IMM_DROWNING            (BIT_R)
-#define IMM_LIGHT		(BIT_S)
-#define IMM_SOUND		(BIT_T)
-#define IMM_WOOD                (BIT_X)
-#define IMM_SILVER              (BIT_Y)
-#define IMM_IRON                (BIT_Z)
-
-/* RES bits for mobs */
-#define RES_SUMMON		(BIT_A)
-#define RES_CHARM		(BIT_B)
-#define RES_MAGIC               (BIT_C)
-#define RES_WEAPON              (BIT_D)
-#define RES_BASH                (BIT_E)
-#define RES_PIERCE              (BIT_F)
-#define RES_SLASH               (BIT_G)
-#define RES_FIRE                (BIT_H)
-#define RES_COLD                (BIT_I)
-#define RES_LIGHTNING           (BIT_J)
-#define RES_ACID                (BIT_K)
-#define RES_POISON              (BIT_L)
-#define RES_NEGATIVE            (BIT_M)
-#define RES_HOLY                (BIT_N)
-#define RES_ENERGY              (BIT_O)
-#define RES_MENTAL              (BIT_P)
-#define RES_DISEASE             (BIT_Q)
-#define RES_DROWNING            (BIT_R)
-#define RES_LIGHT		(BIT_S)
-#define RES_SOUND		(BIT_T)
-#define RES_WOOD                (BIT_X)
-#define RES_SILVER              (BIT_Y)
-#define RES_IRON                (BIT_Z)
-
-/* VULN bits for mobs */
-#define VULN_SUMMON		(BIT_A)
-#define VULN_CHARM		(BIT_B)
-#define VULN_MAGIC              (BIT_C)
-#define VULN_WEAPON             (BIT_D)
-#define VULN_BASH               (BIT_E)
-#define VULN_PIERCE             (BIT_F)
-#define VULN_SLASH              (BIT_G)
-#define VULN_FIRE               (BIT_H)
-#define VULN_COLD               (BIT_I)
-#define VULN_LIGHTNING          (BIT_J)
-#define VULN_ACID               (BIT_K)
-#define VULN_POISON             (BIT_L)
-#define VULN_NEGATIVE           (BIT_M)
-#define VULN_HOLY               (BIT_N)
-#define VULN_ENERGY             (BIT_O)
-#define VULN_MENTAL             (BIT_P)
-#define VULN_DISEASE            (BIT_Q)
-#define VULN_DROWNING           (BIT_R)
-#define VULN_LIGHT		(BIT_S)
-#define VULN_SOUND		(BIT_T)
-#define VULN_WOOD               (BIT_X)
-#define VULN_SILVER             (BIT_Y)
-#define VULN_IRON		(BIT_Z)
-
-/* body form */
-#define FORM_EDIBLE             (BIT_A)
-#define FORM_POISON             (BIT_B)
-#define FORM_MAGICAL            (BIT_C)
-#define FORM_INSTANT_DECAY      (BIT_D)
-#define FORM_OTHER              (BIT_E)	/* defined by material bit */
-
-/* actual form */
-#define FORM_ANIMAL             (BIT_G)
-#define FORM_SENTIENT           (BIT_H)
-#define FORM_UNDEAD             (BIT_I)
-#define FORM_CONSTRUCT          (BIT_J)
-#define FORM_MIST               (BIT_K)
-#define FORM_INTANGIBLE         (BIT_L)
-
-#define FORM_BIPED              (BIT_M)
-#define FORM_CENTAUR            (BIT_N)
-#define FORM_INSECT             (BIT_O)
-#define FORM_SPIDER             (BIT_P)
-#define FORM_CRUSTACEAN         (BIT_Q)
-#define FORM_WORM               (BIT_R)
-#define FORM_BLOB		(BIT_S)
-
-#define FORM_MAMMAL             (BIT_V)
-#define FORM_BIRD               (BIT_W)
-#define FORM_REPTILE            (BIT_X)
-#define FORM_SNAKE              (BIT_Y)
-#define FORM_DRAGON             (BIT_Z)
-#define FORM_AMPHIBIAN          (BIT_a)
-#define FORM_FISH               (BIT_b)
-#define FORM_COLD_BLOOD		(BIT_c)
-
-/* body parts */
-#define PART_HEAD               (BIT_A)
-#define PART_ARMS               (BIT_B)
-#define PART_LEGS               (BIT_C)
-#define PART_HEART              (BIT_D)
-#define PART_BRAINS             (BIT_E)
-#define PART_GUTS               (BIT_F)
-#define PART_HANDS              (BIT_G)
-#define PART_FEET               (BIT_H)
-#define PART_FINGERS            (BIT_I)
-#define PART_EAR                (BIT_J)
-#define PART_EYE		(BIT_K)
-#define PART_LONG_TONGUE        (BIT_L)
-#define PART_EYESTALKS          (BIT_M)
-#define PART_TENTACLES          (BIT_N)
-#define PART_FINS               (BIT_O)
-#define PART_WINGS              (BIT_P)
-#define PART_TAIL               (BIT_Q)
-/* for combat */
-#define PART_CLAWS              (BIT_U)
-#define PART_FANGS              (BIT_V)
-#define PART_HORNS              (BIT_W)
-#define PART_SCALES             (BIT_X)
-#define PART_TUSKS		(BIT_Y)
-
-/*
- * Bits for 'affected_by'.
- * Used in #MOBILES.
- */
-#define AFF_BLIND		(BIT_A)
-#define AFF_INVISIBLE		(BIT_B)
-#define AFF_DETECT_EVIL		(BIT_C)
-#define AFF_DETECT_INVIS	(BIT_D)
-#define AFF_DETECT_MAGIC	(BIT_E)
-#define AFF_DETECT_HIDDEN	(BIT_F)
-#define AFF_DETECT_GOOD		(BIT_G)
-#define AFF_SANCTUARY		(BIT_H)
-#define AFF_FAERIE_FIRE		(BIT_I)
-#define AFF_INFRARED		(BIT_J)
-#define AFF_CURSE		(BIT_K)
-#define AFF_UNUSED_FLAG		(BIT_L)	/* unused */
-#define AFF_POISON		(BIT_M)
-#define AFF_PROTECT_EVIL	(BIT_N)
-#define AFF_PROTECT_GOOD	(BIT_O)
-#define AFF_SNEAK		(BIT_P)
-#define AFF_HIDE		(BIT_Q)
-#define AFF_SLEEP		(BIT_R)
-#define AFF_CHARM		(BIT_S)
-#define AFF_FLYING		(BIT_T)
-#define AFF_PASS_DOOR		(BIT_U)
-#define AFF_HASTE		(BIT_V)
-#define AFF_CALM		(BIT_W)
-#define AFF_PLAGUE		(BIT_X)
-#define AFF_WEAKEN		(BIT_Y)
-#define AFF_DARK_VISION		(BIT_Z)
-#define AFF_BERSERK		(BIT_a)
-#define AFF_SWIM		(BIT_b)
-#define AFF_REGENERATION        (BIT_c)
-#define AFF_SLOW		(BIT_d)
-
-/*
- * Sex.
- * Used in #MOBILES.
- */
-#define SEX_NEUTRAL		      0
-#define SEX_MALE		      1
-#define SEX_FEMALE		      2
-
-/* AC types */
-#define AC_PIERCE			0
-#define AC_BASH				1
-#define AC_SLASH			2
-#define AC_EXOTIC			3
-
-/* dice */
-#define DICE_NUMBER			0
-#define DICE_TYPE			1
-#define DICE_BONUS			2
-
-/* size */
-#define SIZE_TINY			0
-#define SIZE_SMALL			1
-#define SIZE_MEDIUM			2
-#define SIZE_LARGE			3
-#define SIZE_HUGE			4
-#define SIZE_GIANT			5
-
-/*
- * Well known object virtual numbers.
- * Defined in #OBJECTS.
- */
-#define OBJ_VNUM_SILVER_ONE	      1
-#define OBJ_VNUM_GOLD_ONE	      2
-#define OBJ_VNUM_GOLD_SOME	      3
-#define OBJ_VNUM_SILVER_SOME	      4
-#define OBJ_VNUM_COINS		      5
-
-#define OBJ_VNUM_CORPSE_NPC	     10
-#define OBJ_VNUM_CORPSE_PC	     11
-#define OBJ_VNUM_SEVERED_HEAD	     12
-#define OBJ_VNUM_TORN_HEART	     13
-#define OBJ_VNUM_SLICED_ARM	     14
-#define OBJ_VNUM_SLICED_LEG	     15
-#define OBJ_VNUM_GUTS		     16
-#define OBJ_VNUM_BRAINS		     17
-
-#define OBJ_VNUM_MUSHROOM	     20
-#define OBJ_VNUM_LIGHT_BALL	     21
-#define OBJ_VNUM_SPRING		     22
-#define OBJ_VNUM_DISC		     23
-#define OBJ_VNUM_PORTAL		     25
-
-#define OBJ_VNUM_ROSE		   1001
-
-#define OBJ_VNUM_PIT		   3010
-
-#define OBJ_VNUM_SCHOOL_MACE	   3700
-#define OBJ_VNUM_SCHOOL_DAGGER	   3701
-#define OBJ_VNUM_SCHOOL_SWORD	   3702
-#define OBJ_VNUM_SCHOOL_SPEAR	   3717
-#define OBJ_VNUM_SCHOOL_STAFF	   3718
-#define OBJ_VNUM_SCHOOL_AXE	   3719
-#define OBJ_VNUM_SCHOOL_FLAIL	   3720
-#define OBJ_VNUM_SCHOOL_WHIP	   3721
-#define OBJ_VNUM_SCHOOL_POLEARM    3722
-
-#define OBJ_VNUM_SCHOOL_VEST	   3703
-#define OBJ_VNUM_SCHOOL_SHIELD	   3704
-#define OBJ_VNUM_SCHOOL_BANNER     3716
-#define OBJ_VNUM_MAP		   3162
-
-#define OBJ_VNUM_WHISTLE	   2116
-
-#define OBJ_VNUM_TRIVIA_PILL   200
-
-#define QUEST_AURA      201
-#define QUEST_SWORD     203
-#define QUEST_BPLATE    204
-#define QUEST_BOOTS     205
-#define QUEST_GLOVES    206
-#define QUEST_FLAME     207
-#define QUEST_HELM      208
-#define QUEST_BAG       209
-#define QUEST_SHIELD    210
-#define QUEST_REGEN     211
-#define QUEST_INVIS     212
-#define QUEST_TRIVIA    OBJ_VNUM_TRIVIA_PILL
-
-/*
- * Item types.
- * Used in #OBJECTS.
- */
-#define    ITEM_NONE    0
-#define ITEM_LIGHT		      1
-#define ITEM_SCROLL		      2
-#define ITEM_WAND		      3
-#define ITEM_STAFF		      4
-#define ITEM_WEAPON		      5
-#define ITEM_TREASURE		      8
-#define ITEM_ARMOR		      9
-#define ITEM_POTION		     10
-#define ITEM_CLOTHING		     11
-#define ITEM_FURNITURE		     12
-#define ITEM_TRASH		     13
-#define ITEM_CONTAINER		     15
-#define ITEM_DRINK_CON		     17
-#define ITEM_KEY		     18
-#define ITEM_FOOD		     19
-#define ITEM_MONEY		     20
-#define ITEM_BOAT		     22
-#define ITEM_CORPSE_NPC		     23
-#define ITEM_CORPSE_PC		     24
-#define ITEM_FOUNTAIN		     25
-#define ITEM_PILL		     26
-#define ITEM_PROTECT		     27
-#define ITEM_MAP		     28
-#define ITEM_PORTAL		     29
-#define ITEM_WARP_STONE		     30
-#define ITEM_ROOM_KEY		     31
-#define ITEM_GEM		     32
-#define ITEM_JEWELRY		     33
-#define ITEM_JUKEBOX		     34
-
-/*
- * Extra flags.
- * Used in #OBJECTS.
- */
-#define ITEM_GLOW		(BIT_A)
-#define ITEM_HUM		(BIT_B)
-#define ITEM_DARK		(BIT_C)
-#define ITEM_LOCK		(BIT_D)
-#define ITEM_EVIL		(BIT_E)
-#define ITEM_INVIS		(BIT_F)
-#define ITEM_MAGIC		(BIT_G)
-#define ITEM_NODROP		(BIT_H)
-#define ITEM_BLESS		(BIT_I)
-#define ITEM_ANTI_GOOD		(BIT_J)
-#define ITEM_ANTI_EVIL		(BIT_K)
-#define ITEM_ANTI_NEUTRAL	(BIT_L)
-#define ITEM_NOREMOVE		(BIT_M)
-#define ITEM_INVENTORY		(BIT_N)
-#define ITEM_NOPURGE		(BIT_O)
-#define ITEM_ROT_DEATH		(BIT_P)
-#define ITEM_VIS_DEATH		(BIT_Q)
-#define ITEM_AUCTIONED      (BIT_R)
-#define ITEM_NONMETAL		(BIT_S)
-#define ITEM_NOLOCATE		(BIT_T)
-#define ITEM_MELT_DROP		(BIT_U)
-#define ITEM_HAD_TIMER		(BIT_V)
-#define ITEM_SELL_EXTRACT	(BIT_W)
-#define ITEM_BURN_PROOF		(BIT_Y)
-#define ITEM_NOUNCURSE		(BIT_Z)
-#define ITEM_QUEST          (BIT_a)
-
-/*
- * Wear flags.
- * Used in #OBJECTS.
- */
-#define ITEM_TAKE		(BIT_A)
-#define ITEM_WEAR_FINGER	(BIT_B)
-#define ITEM_WEAR_NECK		(BIT_C)
-#define ITEM_WEAR_BODY		(BIT_D)
-#define ITEM_WEAR_HEAD		(BIT_E)
-#define ITEM_WEAR_LEGS		(BIT_F)
-#define ITEM_WEAR_FEET		(BIT_G)
-#define ITEM_WEAR_HANDS		(BIT_H)
-#define ITEM_WEAR_ARMS		(BIT_I)
-#define ITEM_WEAR_SHIELD	(BIT_J)
-#define ITEM_WEAR_ABOUT		(BIT_K)
-#define ITEM_WEAR_WAIST		(BIT_L)
-#define ITEM_WEAR_WRIST		(BIT_M)
-#define ITEM_WIELD		(BIT_N)
-#define ITEM_HOLD		(BIT_O)
-#define ITEM_NO_SAC		(BIT_P)
-#define ITEM_WEAR_FLOAT		(BIT_Q)
-
-/* weapon class */
-#define WEAPON_EXOTIC		0
-#define WEAPON_SWORD		1
-#define WEAPON_DAGGER		2
-#define WEAPON_SPEAR		3
-#define WEAPON_MACE		4
-#define WEAPON_AXE		5
-#define WEAPON_FLAIL		6
-#define WEAPON_WHIP		7
-#define WEAPON_POLEARM		8
-
-/* weapon types */
-#define WEAPON_FLAMING		(BIT_A)
-#define WEAPON_FROST		(BIT_B)
-#define WEAPON_VAMPIRIC		(BIT_C)
-#define WEAPON_SHARP		(BIT_D)
-#define WEAPON_VORPAL		(BIT_E)
-#define WEAPON_TWO_HANDS	(BIT_F)
-#define WEAPON_SHOCKING		(BIT_G)
-#define WEAPON_POISON		(BIT_H)
-
-/* gate flags */
-#define GATE_NORMAL_EXIT	(BIT_A)
-#define GATE_NOCURSE		(BIT_B)
-#define GATE_GOWITH		(BIT_C)
-#define GATE_BUGGY		(BIT_D)
-#define GATE_RANDOM		(BIT_E)
-
-/* furniture flags */
-#define STAND_AT		(BIT_A)
-#define STAND_ON		(BIT_B)
-#define STAND_IN		(BIT_C)
-#define SIT_AT			(BIT_D)
-#define SIT_ON			(BIT_E)
-#define SIT_IN			(BIT_F)
-#define REST_AT			(BIT_G)
-#define REST_ON			(BIT_H)
-#define REST_IN			(BIT_I)
-#define SLEEP_AT		(BIT_J)
-#define SLEEP_ON		(BIT_K)
-#define SLEEP_IN		(BIT_L)
-#define PUT_AT			(BIT_M)
-#define PUT_ON			(BIT_N)
-#define PUT_IN			(BIT_O)
-#define PUT_INSIDE		(BIT_P)
-
-/*
- * Apply types (for affects).
- * Used in #OBJECTS.
- */
-#define APPLY_NONE		      0
-#define APPLY_STR		      1
-#define APPLY_DEX		      2
-#define APPLY_INT		      3
-#define APPLY_WIS		      4
-#define APPLY_CON		      5
-#define APPLY_SEX		      6
-#define APPLY_CLASS		      7
-#define APPLY_LEVEL		      8
-#define APPLY_AGE		      9
-#define APPLY_HEIGHT		     10
-#define APPLY_WEIGHT		     11
-#define APPLY_MANA		     12
-#define APPLY_HIT		     13
-#define APPLY_MOVE		     14
-#define APPLY_GOLD		     15
-#define APPLY_EXP		     16
-#define APPLY_AC		     17
-#define APPLY_HITROLL		     18
-#define APPLY_DAMROLL		     19
-#define APPLY_SAVES		     20
-#define APPLY_SAVING_PARA	     20
-#define APPLY_SAVING_ROD	     21
-#define APPLY_SAVING_PETRI	     22
-#define APPLY_SAVING_BREATH	     23
-#define APPLY_SAVING_SPELL	     24
-#define APPLY_SPELL_AFFECT	     25
-
-/*
- * Values for containers (value[1]).
- * Used in #OBJECTS.
- */
-#define CONT_CLOSEABLE		      1
-#define CONT_PICKPROOF		      2
-#define CONT_CLOSED		      4
-#define CONT_LOCKED		      8
-#define CONT_PUT_ON		     16
-
-/*
- * Well known room virtual numbers.
- * Defined in #ROOMS.
- */
-#define ROOM_VNUM_LIMBO		      2
-#define ROOM_VNUM_CHAT		   1200
-#define ROOM_VNUM_TEMPLE	   3001
-#define ROOM_VNUM_ALTAR		   3054
-#define ROOM_VNUM_SCHOOL	   3700
-#define ROOM_VNUM_WAITROOM     17600
-#define ROOM_VNUM_MORGUE       2
-#define ROOM_VNUM_DUEL_START   17596
-#define ROOM_VNUM_DUEL_END     17597
-#define ROOM_VNUM_DUEL_WINNER  17598
-#define ROOM_VNUM_DUEL_LOSER   17599
-
-/*
- * Room flags.
- * Used in #ROOMS.
- */
-#define ROOM_DARK		(BIT_A)
-#define    HOME_ENTRANCE           (BIT_B)
-#define ROOM_NO_MOB		(BIT_C)
-#define ROOM_INDOORS		(BIT_D)
-#define	ROOM_ARENA       (BIT_E)
-#define ROOM_BANK        (BIT_F)
-#define ROOM_PRIVATE		(BIT_J)
-#define ROOM_SAFE		(BIT_K)
-#define ROOM_SOLITARY		(BIT_L)
-#define ROOM_PET_SHOP		(BIT_M)
-#define ROOM_NO_RECALL		(BIT_N)
-#define ROOM_IMP_ONLY		(BIT_O)
-#define ROOM_GODS_ONLY		(BIT_P)
-#define ROOM_HEROES_ONLY	(BIT_Q)
-#define ROOM_NEWBIES_ONLY	(BIT_R)
-#define ROOM_LAW		(BIT_S)
-#define ROOM_NOWHERE		(BIT_T)
-#define ROOM_NOEXPLORE            (BIT_U)
-#define ROOM_NOAUTOMAP          (BIT_V)
-
-/*
- * Directions.
- * Used in #ROOMS.
- */
-#define DIR_NORTH		      0
-#define DIR_EAST		      1
-#define DIR_SOUTH		      2
-#define DIR_WEST		      3
-#define DIR_UP			      4
-#define DIR_DOWN		      5
-
-/*
- * Exit flags.
- * Used in #ROOMS.
- */
-#define EX_ISDOOR		      (BIT_A)
-#define EX_CLOSED		      (BIT_B)
-#define EX_LOCKED		      (BIT_C)
-#define EX_PICKPROOF		      (BIT_F)
-#define EX_NOPASS		      (BIT_G)
-#define EX_EASY			      (BIT_H)
-#define EX_HARD			      (BIT_I)
-#define EX_INFURIATING		      (BIT_J)
-#define EX_NOCLOSE		      (BIT_K)
-#define EX_NOLOCK		      (BIT_L)
-
-/*
- * Sector types.
- * Used in #ROOMS.
- */
-#define SECT_INSIDE		      0
-#define SECT_CITY		      1
-#define SECT_FIELD		      2
-#define SECT_FOREST		      3
-#define SECT_HILLS		      4
-#define SECT_MOUNTAIN		      5
-#define SECT_WATER_SWIM		      6
-#define SECT_WATER_NOSWIM	      7
-#define SECT_UNUSED		      8
-#define SECT_AIR		      9
-#define SECT_DESERT		     10
-#define SECT_MAX		     11
-
-/*
- * Equpiment wear locations.
- * Used in #RESETS.
- */
-#define WEAR_NONE		     -1
-#define WEAR_LIGHT		      0
-#define WEAR_FINGER_L		      1
-#define WEAR_FINGER_R		      2
-#define WEAR_NECK_1		      3
-#define WEAR_NECK_2		      4
-#define WEAR_BODY		      5
-#define WEAR_HEAD		      6
-#define WEAR_LEGS		      7
-#define WEAR_FEET		      8
-#define WEAR_HANDS		      9
-#define WEAR_ARMS		     10
-#define WEAR_SHIELD		     11
-#define WEAR_ABOUT		     12
-#define WEAR_WAIST		     13
-#define WEAR_WRIST_L		     14
-#define WEAR_WRIST_R		     15
-#define WEAR_WIELD		     16
-#define WEAR_HOLD		     17
-#define WEAR_FLOAT		     18
-#define WEAR_SECONDARY               19
-#define MAX_WEAR                     20
-
-/***************************************************************************
- *                                                                         *
- *                   VALUES OF INTEREST TO AREA BUILDERS                   *
- *                   (End of this section ... stop here)                   *
- *                                                                         *
- ***************************************************************************/
-
-/*
- * Conditions.
- */
-#define COND_DRUNK		      0
-#define COND_FULL		      1
-#define COND_THIRST		      2
-#define COND_HUNGER		      3
-
-/*
- * Positions.
- */
-#define POS_DEAD		      0
-#define POS_MORTAL		      1
-#define POS_INCAP		      2
-#define POS_STUNNED		      3
-#define POS_SLEEPING		      4
-#define POS_RESTING		      5
-#define POS_SITTING		      6
-#define POS_FIGHTING		      7
-#define POS_STANDING		      8
-
-/*
- * ACT bits for players.
- */
-#define PLR_IS_NPC		    (BIT_A)	/* Don't EVER set.  */
-#define    PLR_AUTOMAP             (BIT_B)
-/* RT auto flags */
-#define PLR_AUTOASSIST		(BIT_C)
-#define PLR_AUTOEXIT		(BIT_D)
-#define PLR_AUTOLOOT		(BIT_E)
-#define PLR_AUTOSAC         (BIT_F)
-#define PLR_AUTOGOLD		(BIT_G)
-#define PLR_AUTOSPLIT		(BIT_H)
-
-#define PLR_AUTODAMAGE  (BIT_K)
-
-/* Arena flags */
-#define PLR_CHALLENGED  (BIT_L)
-#define PLR_CHALLENGER  (BIT_M)
-
-/* RT personal flags */
-#define PLR_HOLYLIGHT		(BIT_N)
-#define PLR_CANLOOT		    (BIT_P)
-#define PLR_NOSUMMON		(BIT_Q)
-#define PLR_NOFOLLOW		(BIT_R)
-/* 2 bits reserved, S-T */
-
-/* penalty flags */
-#define PLR_PERMIT		(BIT_U)
-#define PLR_LOG			(BIT_W)
-#define PLR_DENY		(BIT_X)
-#define PLR_FREEZE		(BIT_Y)
-#define PLR_THIEF		(BIT_Z)
-#define PLR_KILLER		(BIT_a)
-#define PLR_QUESTOR     (BIT_b)
-#define PLR_REMORT      (BIT_c)
-
-/* RT comm flags -- may be used on both mobs and chars */
-#define COMM_QUIET              (BIT_A)
-#define COMM_DEAF            	(BIT_B)
-#define COMM_NOWIZ              (BIT_C)
-#define COMM_NOAUCTION          (BIT_D)
-#define COMM_NOGOSSIP           (BIT_E)
-#define COMM_NOQUESTION         (BIT_F)
-#define COMM_NOMUSIC            (BIT_G)
-#define COMM_NOCLAN		        (BIT_H)
-#define COMM_NOQUOTE		    (BIT_I)
-#define COMM_SHOUTSOFF		    (BIT_J)
-
-#define COMM_NOCOLOUR           (BIT_K)
-
-/* display flags */
-#define COMM_COMPACT		(BIT_L)
-#define COMM_BRIEF		    (BIT_M)
-#define COMM_PROMPT		    (BIT_N)
-#define COMM_COMBINE		(BIT_O)
-#define COMM_TELNET_GA		(BIT_P)
-#define COMM_SHOW_AFFECTS	(BIT_Q)
-#define COMM_NOGRATS		(BIT_R)
-#define COMM_TELNET_EOR	    (BIT_S)	/* End Of Record - from telnet negotiation */
-
-/* penalties */
-#define COMM_NOEMOTE		(BIT_T)
-#define COMM_NOSHOUT		(BIT_U)
-#define COMM_NOTELL		    (BIT_V)
-#define COMM_NOCHANNELS		(BIT_W)
-#define COMM_SNOOP_PROOF	(BIT_Y)
-#define COMM_AFK		    (BIT_Z)
-#define COMM_NOGOCIAL       (BIT_a)
-#define COMM_NOOOC          (BIT_b)
-#define    COMM_NOBUDDY            (BIT_c)
-
-/* WIZnet flags */
-#define WIZ_ON			(BIT_A)
-#define WIZ_TICKS		(BIT_B)
-#define WIZ_LOGINS		(BIT_C)
-#define WIZ_SITES		(BIT_D)
-#define WIZ_LINKS		(BIT_E)
-#define WIZ_DEATHS		(BIT_F)
-#define WIZ_RESETS		(BIT_G)
-#define WIZ_MOBDEATHS		(BIT_H)
-#define WIZ_FLAGS		(BIT_I)
-#define WIZ_PENALTIES		(BIT_J)
-#define WIZ_SACCING		(BIT_K)
-#define WIZ_LEVELS		(BIT_L)
-#define WIZ_SECURE		(BIT_M)
-#define WIZ_SWITCHES		(BIT_N)
-#define WIZ_SNOOPS		(BIT_O)
-#define WIZ_RESTORE		(BIT_P)
-#define WIZ_LOAD		(BIT_Q)
-#define WIZ_NEWBIE		(BIT_R)
-#define WIZ_PREFIX		(BIT_S)
-#define WIZ_SPAM		(BIT_T)
-#define WIZ_BUGS        (BIT_U)
-
-#define	WAR_OFF     0
-#define	WAR_WAITING 1
-#define	WAR_RUNNING 2
-
-enum war_types
-{
-	WAR_NONE = 0,
-	WAR_CLAN = 1,
-	WAR_RACE = 2,
-	WAR_CLASS = 3,
-	WAR_GENOCIDE = 4,
-	WAR_DEITY = 5,
-	WAR_SEX = 6,
-	MAX_WAR = 7
-};
-
-struct war_list_type
-{
-	WAR_LIST *next, *prev;
-	CHAR_DATA *ch;
-	long hit, mana, move;
-	flag_t flags;
-};
-
-struct war_data
-{
-	WAR_LIST *first, *last;
-	const char *who;
-	int min_level;
-	int max_level;
-	int inwar;
-	enum war_types wartype;
-	int timer;
-	int status;
-};
-
-struct wpwd_data
-{
-	WPWD_DATA *next;
-	WPWD_DATA *prev;
-	bool valid;
-	const char *name;
-	const char *passw;
-};
-
-#define INFO_ALL        (BIT_A)
-#define INFO_QUIET      (BIT_B)
-#define INFO_LOGIN      (BIT_C)
-#define INFO_LOGOUT     (BIT_D)
-#define INFO_DEATH      (BIT_E)
-#define INFO_NOTE       (BIT_F)
-#define INFO_LEVEL      (BIT_G)
-#define INFO_PRIVATE    (BIT_H)
-#define INFO_WAR        (BIT_I)
-#define INFO_GQUEST     (BIT_J)
-#define INFO_AUCTION    (BIT_K)
-#define INFO_ARENA      (BIT_L)
-
-/*
- * Prototype for a mob.
- * This is the in-memory version of #MOBILES.
- */
-struct mob_index_data
-{
-	MOB_INDEX_DATA *next;
-	SPEC_FUN *spec_fun;
-	SHOP_DATA *pShop;
-	PROG_LIST *first_mprog;
-	PROG_LIST *last_mprog;
-	AREA_DATA *area;			/* OLC */
-	vnum_t vnum;
-	vnum_t group;
-	bool new_format;
-	int count;
-	int killed;
-	const char *player_name;
-	const char *short_descr;
-	const char *long_descr;
-	const char *description;
-	flag_t act;
-	flag_t affected_by;
-	int alignment;
-	int level;
-	int hitroll;
-	int hit[3];
-	int mana[3];
-	int damage[3];
-	int ac[4];
-	int dam_type;
-	flag_t off_flags;
-	flag_t imm_flags;
-	flag_t res_flags;
-	flag_t vuln_flags;
-	int start_pos;
-	int default_pos;
-	int sex;
-	RACE_DATA *race;
-	long wealth;
-	flag_t form;
-	flag_t parts;
-	int size;
-	const char *material;
-	flag_t mprog_flags;
-};
-
-/* memory settings */
-#define MEM_CUSTOMER	A
-#define MEM_SELLER	B
-#define MEM_HOSTILE	C
-#define MEM_AFRAID	D
-
-/* memory for mobs */
-struct mem_data
-{
-	MEM_DATA *next;
-	MEM_DATA *prev;
-	bool valid;
-	int id;
-	int reaction;
-	time_t when;
-};
-
-#define PK_KILLS         0
-#define MOB_KILLS        1
-#define PK_DEATHS        2
-#define MOB_DEATHS       3
-#define MAX_GAMESTAT     4
-
-struct stat_data
-{
-	STAT_DATA *next;
-	STAT_DATA *prev;
-	bool valid;
-	const char *name;			// name of character
-	long gamestat[MAX_GAMESTAT];	// stat data
-};
-
-struct mbr_data
-{
-	MBR_DATA *next;
-	MBR_DATA *prev;
-	bool valid;
-	const char *name;
-	int rank;
-	CLAN_DATA *clan;
-	int level;
-};
-
-/*
- * One character (PC or NPC).
- */
-struct char_data
-{
-	CHAR_DATA *next;
-	CHAR_DATA *prev;
-	CHAR_DATA *next_player;
-	CHAR_DATA *prev_player;
-	CHAR_DATA *next_in_room;
-	CHAR_DATA *prev_in_room;
-	CHAR_DATA *master;
-	CHAR_DATA *leader;
-	CHAR_DATA *fighting;
-	CHAR_DATA *reply;
-	CHAR_DATA *pet;
-	CHAR_DATA *mprog_target;
-	MEM_DATA *memory;
-	SPEC_FUN *spec_fun;
-	MOB_INDEX_DATA *pIndexData;
-	DESCRIPTOR_DATA *desc;
-	AFFECT_DATA *first_affect;
-	AFFECT_DATA *last_affect;
-	OBJ_DATA *first_carrying;
-	OBJ_DATA *last_carrying;
-	OBJ_DATA *on;
-	ROOM_INDEX_DATA *in_room;
-	ROOM_INDEX_DATA *was_in_room;
-	AREA_DATA *zone;
-	PC_DATA *pcdata;
-	GEN_DATA *gen_data;
-	CHAR_DATA *hunting;
-	WAR_LIST *war;
-	GQ_LIST *gquest;
-	bool valid;
-	const char *name;
-	long id;
-	int version;
-	const char *short_descr;
-	const char *long_descr;
-	const char *description;
-	const char *prompt;
-	const char *prefix;
-	int group;
-	CLAN_DATA *clan;
-	int sex;
-	int rank;
-	CLAN_DATA *invited;
-	int Class[MAX_MCLASS];
-	RACE_DATA *race;
-	int level;
-	DEITY_DATA *deity;
-	int trust;
-	int played;
-	int lines;					/* for the pager */
-	time_t logon;
-	int timer;
-	int wait;
-	int daze;
-	long hit;
-	long max_hit;
-	long mana;
-	long max_mana;
-	long move;
-	long max_move;
-	long gold;
-	long silver;
-	int exp;
-	flag_t act;
-	flag_t comm;				/* RT added to pad the vector */
-	flag_t wiznet;				/* wiz stuff */
-	flag_t imm_flags;
-	flag_t res_flags;
-	flag_t vuln_flags;
-	int invis_level;
-	int incog_level;
-	flag_t affected_by;
-	int position;
-	int practice;
-	int train;
-	int carry_weight;
-	int carry_number;
-	int saving_throw;
-	int alignment;
-	int hitroll;
-	int damroll;
-	int armor[4];
-	int wimpy;
-	/* stats */
-	int perm_stat[MAX_STATS];
-	int mod_stat[MAX_STATS];
-	/* parts stuff */
-	flag_t form;
-	flag_t parts;
-	int size;
-	const char *material;
-	/* mobile stuff */
-	flag_t off_flags;
-	int damage[3];
-	int dam_type;
-	int start_pos;
-	int default_pos;
-	flag_t info_settings;
-
-	int mprog_delay;
-};
-
-/* Arena Defines */
-#define FIGHT_OPEN 0
-#define FIGHT_START 1
-#define FIGHT_BUSY 2
-#define FIGHT_LOCK 3
-
-#define LAST_PAGE_LENGTH    20
-
-#define LAST_NONE        -1
-#define LAST_IMMTALK    0
-#define LAST_GOSSIP        1
-#define LAST_QA            2
-#define LAST_MUSIC        3
-#define LAST_CLANTALK    4
-#define LAST_QUOTE        5
-#define LAST_GRATS        6
-#define LAST_BTALK        7
-#define LAST_OOC          8
-#define LAST_MAX        9
-
-#define CHANNEL_NORMAL 0
-#define CHANNEL_SOCIAL 1
-#define CHANNEL_EMOTE  2
-
-/*
- * Data which only PC's have.
- */
-struct pc_data
-{
-	PC_DATA *next;
-	PC_DATA *prev;
-	BUFFER *buffer;
-	CHAR_DATA *challenger;
-	CHAR_DATA *challenged;
-	CHAR_DATA *gladiator;
-	bool valid;
-	const char *pwd;
-	const char *bamfin;
-	const char *bamfout;
-	const char *title;
-	const char *who_descr;
-	long perm_hit;
-	long perm_mana;
-	long perm_move;
-	int true_sex;
-	int last_level;
-	int condition[4];
-	int *learned;
-	bool *group_known;
-	int points;
-	bool confirm_delete;
-	BOARD_DATA *board;			/* The current board        */
-	time_t last_note[MAX_BOARD];	/* last note for the boards */
-	NOTE_DATA *in_progress;
-	const char *alias[MAX_ALIAS];
-	const char *alias_sub[MAX_ALIAS];
-	int security;				/* OLC *//* Builder security */
-	int colour[MAX_CUSTOM_COLOUR][3];
-	long gamestat[MAX_GAMESTAT];
-	int nextquest;
-	int countdown;
-	vnum_t questobj;
-	vnum_t questmob;
-	vnum_t questgiver;
-	vnum_t questloc;
-	int questpoints;
-	int trivia;
-	bool confirm_remort;
-	bool stay_race;
-	char explored[MAX_EXPLORE_HASH];
-	long home_invite;
-	vnum_t home[MAX_HOUSE_ROOMS];
-	vnum_t home_key;
-	int awins;
-	int alosses;
-	int plr_wager;
-	long gold_bank;
-	long silver_bank;
-	int shares;
-	const char *webpass;
-	char str_ed_key;
-	const char *buddies[MAX_BUDDY];
-	const char *history[LAST_MAX][LAST_PAGE_LENGTH];
-	int timezone;
-};
-
-/* Data for generating characters -- only used during generation */
-struct gen_data
-{
-	GEN_DATA *next;
-	GEN_DATA *prev;
-	bool valid;
-	bool *skill_chosen;
-	bool *group_chosen;
-	int points_chosen;
-};
-
-/*
- * Liquids.
- */
-#define LIQ_WATER        0
-
-struct liq_type
-{
-	const char *liq_name;
-	const char *liq_color;
-	int liq_affect[5];
-};
-
-/*
- * Extra description data for a room or object.
- */
-struct extra_descr_data
-{
-	EXTRA_DESCR_DATA *next;
-	EXTRA_DESCR_DATA *prev;		/* Next in list                     */
-	bool valid;
-	const char *keyword;		/* Keyword in look/examine          */
-	const char *description;	/* What to see                      */
-};
-
-/*
- * Prototype for an object.
- */
-struct obj_index_data
-{
-	OBJ_INDEX_DATA *next;
-	EXTRA_DESCR_DATA *first_extra_descr;
-	EXTRA_DESCR_DATA *last_extra_descr;
-	AFFECT_DATA *first_affect;
-	AFFECT_DATA *last_affect;
-	PROG_LIST *first_oprog;
-	PROG_LIST *last_oprog;
-	AREA_DATA *area;			/* OLC */
-	bool new_format;
-	const char *name;
-	const char *short_descr;
-	const char *description;
-	vnum_t vnum;
-	int reset_num;
-	const char *material;
-	int item_type;
-	flag_t extra_flags;
-	flag_t wear_flags;
-	int level;
-	int condition;
-	int count;
-	int weight;
-	int cost;
-	long value[5];
-	flag_t oprog_flags;
-};
-
-/*
- * One object.
- */
-struct obj_data
-{
-	OBJ_DATA *next;
-	OBJ_DATA *prev;
-	OBJ_DATA *next_content;
-	OBJ_DATA *prev_content;
-	OBJ_DATA *first_content;
-	OBJ_DATA *last_content;
-	OBJ_DATA *in_obj;
-	OBJ_DATA *on;
-	CHAR_DATA *carried_by;
-	EXTRA_DESCR_DATA *first_extra_descr;
-	EXTRA_DESCR_DATA *last_extra_descr;
-	AFFECT_DATA *first_affect;
-	AFFECT_DATA *last_affect;
-	OBJ_INDEX_DATA *pIndexData;
-	ROOM_INDEX_DATA *in_room;
-	CHAR_DATA *oprog_target;
-	int oprog_delay;
-	bool valid;
-	bool enchanted;
-	const char *owner;
-	const char *name;
-	const char *short_descr;
-	const char *description;
-	int item_type;
-	flag_t extra_flags;
-	flag_t wear_flags;
-	int wear_loc;
-	int weight;
-	int cost;
-	int level;
-	int condition;
-	const char *material;
-	int timer;
-	long value[5];
-};
-
-/*
- * Exit data.
- */
-struct exit_data
-{
-	union
-	{
-		ROOM_INDEX_DATA *to_room;
-		vnum_t vnum;
-	}
-	u1;
-	flag_t exit_info;
-	vnum_t key;
-	const char *keyword;
-	const char *description;
-	EXIT_DATA *next;
-	EXIT_DATA *prev;			/* OLC */
-	flag_t rs_flags;			/* OLC */
-	int orig_door;				/* OLC */
-};
-
-/*
- * Reset commands:
- *   '*': comment
- *   'M': read a mobile 
- *   'O': read an object
- *   'P': put object in object
- *   'G': give object to mobile
- *   'E': equip object to mobile
- *   'D': set state of door
- *   'R': randomize room exits
- *   'S': stop (end of list)
- */
-
-/*
- * Area-reset definition.
- */
-struct reset_data
-{
-	RESET_DATA *next;
-	RESET_DATA *prev;
-	char command;
-	vnum_t arg1;
-	int arg2;
-	vnum_t arg3;
-	int arg4;
-};
-
-/*
- * Area definition.
- */
-struct area_data
-{
-	AREA_DATA *next;
-	AREA_DATA *prev;
-	AREA_DATA *next_sort;
-	const char *file_name;
-	const char *name;
-	const char *credits;
-	const char *lvl_comment;
-	int version;
-	int age;
-	int nplayer;
-	int min_level;
-	int max_level;
-	vnum_t min_vnum;
-	vnum_t max_vnum;
-	bool empty;
-	const char *builders;		/* OLC *//* Listing of */
-	int vnum;					/* OLC *//* Area vnum  */
-	flag_t area_flags;			/* OLC */
-	int security;				/* OLC *//* Value 1-9  */
-};
-
-/*
- * Room type.
- */
-struct room_index_data
-{
-	ROOM_INDEX_DATA *next;
-	CHAR_DATA *first_person;
-	CHAR_DATA *last_person;
-	OBJ_DATA *first_content;
-	OBJ_DATA *last_content;
-	EXTRA_DESCR_DATA *first_extra_descr;
-	EXTRA_DESCR_DATA *last_extra_descr;
-	AREA_DATA *area;
-	EXIT_DATA *exit[6];
-	RESET_DATA *reset_first;	/* OLC */
-	RESET_DATA *reset_last;		/* OLC */
-	PROG_LIST *first_rprog;
-	PROG_LIST *last_rprog;
-	CHAR_DATA *rprog_target;
-	flag_t rprog_flags;
-	int rprog_delay;
-	const char *name;
-	const char *description;
-	const char *owner;
-	vnum_t vnum;
-	flag_t room_flags;
-	int light;
-	int sector_type;
-	int heal_rate;
-	int mana_rate;
-	CLAN_DATA *clan;
-};
-
- /* one disabled command */
-struct disabled_data
-{
-	DISABLED_DATA *next;
-	DISABLED_DATA *prev;		/* pointer to next node */
-	struct cmd_type const *command;	/* pointer to the command struct */
-	const char *disabled_by;	/* name of disabler */
-	int level;					/* level of disabler */
-};
-
-/*
- * Types of attacks.
- * Must be non-overlapping with spell/skill types,
- * but may be arbitrary beyond that.
- */
-#define TYPE_UNDEFINED               -1
-#define TYPE_HIT                     1000
-
-/*
- *  Target types.
- */
-#define TAR_IGNORE		    0
-#define TAR_CHAR_OFFENSIVE	    1
-#define TAR_CHAR_DEFENSIVE	    2
-#define TAR_CHAR_SELF		    3
-#define TAR_OBJ_INV		    4
-#define TAR_OBJ_CHAR_DEF	    5
-#define TAR_OBJ_CHAR_OFF	    6
-
-#define TARGET_CHAR		    0
-#define TARGET_OBJ		    1
-#define TARGET_ROOM		    2
-#define TARGET_NONE		    3
-
-/*
- * Skills include spells as a particular case.
- */
-struct skill_type
-{
-	const char *name;			/* Name of skill        */
-	int *skill_level;			/* Level needed by class    */
-	int *rating;				/* How hard it is to learn  */
-	SPELL_FUN *spell_fun;		/* Spell pointer (for spells)   */
-	int target;					/* Legal targets        */
-	int minimum_position;		/* Position for caster / user   */
-	int *pgsn;					/* Pointer to associated gsn    */
-	int min_mana;				/* Minimum mana used        */
-	int beats;					/* Waiting time after use   */
-	const char *noun_damage;	/* Damage message       */
-	const char *msg_off;		/* Wear off message     */
-	const char *msg_obj;		/* Wear off message for obects  */
-};
-
-struct group_type
-{
-	const char *name;
-	int *rating;
-	const char *spells[MAX_IN_GROUP];
-};
-
-/*
- * MOBprog definitions
- */
-#define TRIG_ACT	(BIT_A)
-#define TRIG_BRIBE	(BIT_B)
-#define TRIG_DEATH	(BIT_C)
-#define TRIG_ENTRY	(BIT_D)
-#define TRIG_FIGHT	(BIT_E)
-#define TRIG_GIVE	(BIT_F)
-#define TRIG_GREET	(BIT_G)
-#define TRIG_GRALL	(BIT_H)
-#define TRIG_KILL	(BIT_I)
-#define TRIG_HPCNT	(BIT_J)
-#define TRIG_RANDOM	(BIT_K)
-#define TRIG_SPEECH	(BIT_L)
-#define TRIG_EXIT	(BIT_M)
-#define TRIG_EXALL	(BIT_N)
-#define TRIG_DELAY	(BIT_O)
-#define TRIG_SURR	(BIT_P)
-#define TRIG_GET	(BIT_Q)
-#define TRIG_DROP	(BIT_R)
-#define TRIG_SIT	(BIT_S)
-
-#define PRG_MPROG	0
-#define PRG_OPROG	1
-#define PRG_RPROG	2
-
-struct prog_list
-{
-	flag_t trig_type;
-	const char *trig_phrase;
-	vnum_t vnum;
-	const char *code;
-	PROG_LIST *next;
-	PROG_LIST *prev;
-	bool valid;
-};
-
-struct prog_code
-{
-	vnum_t vnum;
-	const char *code;
-	PROG_CODE *next;
-	PROG_CODE *prev;
-};
+#include "structs.h"
 
-#include <limits.h>				// PATH_MAX
-
-#if !defined(PATH_MAX)
-#define PATH_MAX 512
-#endif
-
-struct file_data
-{
-	FILE *file;
-	char tmp_name[PATH_MAX];
-	char name[PATH_MAX];
-};
+#include "bits.h"
 
 #include "gsn.h"
 
-/*
- * Utility macros.
- */
-#define IS_VALID(data)		((data) != NULL && (data)->valid)
-#define VALIDATE(data)		((data)->valid = TRUE)
-#define INVALIDATE(data)	((data)->valid = FALSE)
-#define	UMIN(a, b)              ((a) < (b) ? (a) : (b))
-#define	UMAX(a, b)              ((a) > (b) ? (a) : (b))
-#define	URANGE(a, b, c)         ((b) < (a) ? (a) : ((b) > (c) ? (c) : (b)))
-#define	LOWER(c)                ((c) >= 'A' && (c) <= 'Z' ? (c)+'a'-'A' : (c))
-#define	UPPER(c)                ((c) >= 'a' && (c) <= 'z' ? (c)+'A'-'a' : (c))
-#define IS_SET(flag, bit)	((flag) & (bit))
-#define SET_BIT(var, bit)	((var) |= (bit))
-#define REMOVE_BIT(var, bit)	((var) &= ~(bit))
-/* bit string operations */
-#define    STR_IS_SET(var, bit)     ((((char *)(var))[((bit)/8)]) &   ((1<<((bit)%8))))
-#define    STR_SET_BIT(var, bit)    ((((char *)(var))[((bit)/8)]) |=  ((1<<((bit)%8))))
-#define    STR_REMOVE_BIT(var, bit) ((((char *)(var))[((bit)/8)]) &= ~((1<<((bit)%8))))
-#define    STR_TOGGLE_BIT(var, bit) ((((char *)(var))[((bit)/8)]) ^=  ((1<<((bit)%8))))
-
-#define IS_NULLSTR(str)		((str) == NULL || (str)[0] == '\0')
-#define ENTRE(min,num,max)	( ((min) < (num)) && ((num) < (max)) )
-#define	CHECK_POS(a, b, c)      {                                                       \
-	(a) = (b);                                  \
-	if ( (a) < 0 )                                      \
-					bug( "CHECK_POS : " c " == %d < 0", a );	\
-				}
-
-#define UNLINK_SINGLE(pdata,pnext,type,list) \
-do                                          \
-{                                          \
-	if (list == pdata)                      \
-	{                                       \
-		list = pdata->pnext;                 \
-	}                                       \
-	else                                    \
-	{                                       \
-		type *prev;                         \
-		for (prev = list; prev != NULL; prev = prev->pnext) \
-		{                                   \
-			if (prev->pnext == pdata)        \
-			{                               \
-				prev->pnext = pdata->pnext;   \
-				break;                      \
-			}                               \
-		}                                   \
-		if (prev == NULL)                   \
-		{                                   \
-			bugf (#pdata " not found in " #list "."); \
-		}                                   \
-	}                                       \
-} while(0)
-
-#define LINK_SINGLE(pdata,pnext,list) \
-do \
-{ \
-		pdata->pnext = list; \
-		list = pdata; \
-} \
-while (0)
-
-#define LINK_LAST(pdata,pnext,type,list) \
-do \
-{ \
-    type *tmp; \
-    if((tmp = list) == NULL) \
-    { \
-		pdata->pnext = list; \
-		list = pdata; \
-        break; \
-    } \
-    for(; tmp; tmp = tmp->pnext) \
-    { \
-        if(!tmp->pnext) \
-        { \
-            tmp->pnext = pdata; \
-            pdata->pnext = NULL; \
-            break; \
-        } \
-    } \
-} \
-while (0)
-
-#define LINK(link, first, last, next, prev)                     	\
-do                                                              	\
-{                                                               	\
-   if ( !(first) )								\
-   {                                           				\
-      (first) = (link);				                       	\
-      (last) = (link);							    	\
-   }											\
-   else                                                      	\
-      (last)->next = (link);			                       	\
-   (link)->next = NULL;			                         	\
-   if (first == link)								\
-      (link)->prev = NULL;							\
-   else										\
-      (link)->prev = (last);			                       	\
-   (last) = (link);				                       	\
-} while(0)
-
-#define INSERT(link, insert, first, next, prev)                 \
-do                                                              \
-{                                                               \
-   (link)->prev = (insert)->prev;			                \
-   if ( !(insert)->prev )                                       \
-      (first) = (link);                                         \
-   else                                                         \
-      (insert)->prev->next = (link);                            \
-   (insert)->prev = (link);                                     \
-   (link)->next = (insert);                                     \
-} while(0)
-
-#define UNLINK(link, first, last, next, prev)                   	\
-do                                                              	\
-{                                                               	\
-	if ( !(link)->prev )							\
-	{			                                    	\
-         (first) = (link)->next;			                 	\
-	   if ((first))							 	\
-	      (first)->prev = NULL;						\
-	} 										\
-	else										\
-	{                                                 		\
-         (link)->prev->next = (link)->next;                 	\
-	}										\
-	if ( !(link)->next ) 							\
-	{				                                    \
-         (last) = (link)->prev;                 			\
-	   if ((last))								\
-	      (last)->next = NULL;						\
-	} 										\
-	else										\
-	{                                                    		\
-         (link)->next->prev = (link)->prev;                 	\
-	}										\
-} while(0)
-
-#define CHECK_LINKS(first, last, next, prev, type)		\
-do {								\
-  type *ptr, *pptr = NULL;					\
-  if ( !(first) && !(last) )					\
-    break;							\
-  if ( !(first) )						\
-  {								\
-    bugf( "CHECK_LINKS: last with NULL first!  %s.",		\
-        #first );					\
-    for ( ptr = (last); ptr->prev; ptr = ptr->prev );		\
-    (first) = ptr;						\
-  }								\
-  else if ( !(last) )						\
-  {								\
-    bugf( "CHECK_LINKS: first with NULL last!  %s.",		\
-        #first );					\
-    for ( ptr = (first); ptr->next; ptr = ptr->next );		\
-    (last) = ptr;						\
-  }								\
-  if ( (first) )						\
-  {								\
-    for ( ptr = (first); ptr; ptr = ptr->next )			\
-    {								\
-      if ( ptr->prev != pptr )					\
-      {								\
-        bugf( "CHECK_LINKS(%s): %p:->prev != %p.  Fixing.",	\
-            #first, ptr, pptr );			\
-        ptr->prev = pptr;					\
-      }								\
-      if ( ptr->prev && ptr->prev->next != ptr )		\
-      {								\
-        bugf( "CHECK_LINKS(%s): %p:->prev->next != %p.  Fixing.",\
-            #first, ptr, ptr );			\
-        ptr->prev->next = ptr;					\
-      }								\
-      pptr = ptr;						\
-    }								\
-    pptr = NULL;						\
-  }								\
-  if ( (last) )							\
-  {								\
-    for ( ptr = (last); ptr; ptr = ptr->prev )			\
-    {								\
-      if ( ptr->next != pptr )					\
-      {								\
-        bugf( "CHECK_LINKS (%s): %p:->next != %p.  Fixing.",	\
-            #first, ptr, pptr );			\
-        ptr->next = pptr;					\
-      }								\
-      if ( ptr->next && ptr->next->prev != ptr )		\
-      {								\
-        bugf( "CHECK_LINKS(%s): %p:->next->prev != %p.  Fixing.",\
-            #first, ptr, ptr );			\
-        ptr->next->prev = ptr;					\
-      }								\
-      pptr = ptr;						\
-    }								\
-  }								\
-} while(0)
-
-#define replace_string(astr, bstr)  do{ free_string(astr); astr = str_dup(bstr); }while(0)
-
-#define IS_STRSET(str)  ((str == NULL || str[0] == '\0') ? "Not set." : str)
-
-/*
- * Character macros.
- */
-#define IS_NPC(ch)		(IS_SET((ch)->act, ACT_IS_NPC))
-#define IS_IMMORTAL(ch)		(get_trust(ch) >= LEVEL_IMMORTAL)
-#define IS_HERO(ch)		(get_trust(ch) >= LEVEL_HERO)
-#define IS_TRUSTED(ch,level)	(get_trust((ch)) >= (level))
-#define IS_AFFECTED(ch, sn)	(IS_SET((ch)->affected_by, (sn)))
-
-#define GET_AGE(ch)		((int) (17 + ((ch)->played \
-				    + current_time - (ch)->logon )/72000))
-
-#define IS_GOOD(ch)		(ch->alignment >= 350)
-#define IS_EVIL(ch)		(ch->alignment <= -350)
-#define IS_NEUTRAL(ch)		(!IS_GOOD(ch) && !IS_EVIL(ch))
-
-#define IS_AWAKE(ch)		(ch->position > POS_SLEEPING)
-#define GET_AC(ch,type)		((ch)->armor[type]			    \
-		        + ( IS_AWAKE(ch)			    \
-			? dex_app[get_curr_stat(ch,STAT_DEX)].defensive : 0 ))
-#define GET_HITROLL(ch)	\
-		((ch)->hitroll+str_app[get_curr_stat(ch,STAT_STR)].tohit)
-#define GET_DAMROLL(ch) \
-		((ch)->damroll+str_app[get_curr_stat(ch,STAT_STR)].todam)
-
-#define IS_OUTSIDE(ch)		(!IS_SET(				    \
-				    (ch)->in_room->room_flags,		    \
-				    ROOM_INDOORS))
-#define IS_IN_WAR(ch)   (ch->war != NULL \
-                        && IS_SET((ch)->in_room->room_flags, ROOM_ARENA))
-
-#define WAIT_STATE(ch, npulse)	((ch)->wait = UMAX((ch)->wait, (npulse)))
-#define DAZE_STATE(ch, npulse)  ((ch)->daze = UMAX((ch)->daze, (npulse)))
-#define get_carry_weight(ch)	((ch)->carry_weight + (ch)->silver/10 +  \
-						      (ch)->gold * 2 / 5)
-
-#define act(format,ch,arg1,arg2,type)\
-	act_new((format),(ch),(arg1),(arg2),(type),POS_RESTING)
-
-#define HAS_TRIGGER_MOB(ch,trig)	(IS_SET((ch)->pIndexData->mprog_flags,(trig)))
-#define HAS_TRIGGER_OBJ(obj,trig) (IS_SET((obj)->pIndexData->oprog_flags,(trig)))
-#define HAS_TRIGGER_ROOM(room,trig) (IS_SET((room)->rprog_flags,(trig)))
-
-#define IS_SWITCHED( ch )       ( ch->desc && ch->desc->original )
-#define IS_BUILDER(ch, Area)	( !IS_NPC(ch) && !IS_SWITCHED( ch ) &&	  \
-				( ch->pcdata->security >= Area->security  \
-				|| strstr( Area->builders, ch->name )	  \
-				|| strstr( Area->builders, "All" ) ) )
-
-#define DESC_FLAGGED(d, flag) (IS_SET((d)->d_flags, (flag)))
-
-#define CH(descriptor)  ((descriptor)->original ? \
-(descriptor)->original : (descriptor)->character)
-
-#define IS_REMORT(ch)      (!IS_NPC(ch) && ( IS_SET((ch)->act, PLR_REMORT) \
-                                || number_classes(ch) > 1))
-
-#define	ON_GQUEST(ch)      (gquest_info.running != GQUEST_OFF && ch->gquest)
-
-#define STR_EDIT_KEY(ch) (IS_NPC(ch) ? '.' : ch->pcdata->str_ed_key)
-
-#define GET_TZONE(ch)   (IS_NPC(ch) ? -1 : ch->pcdata->timezone)
-
-/*
- * Object macros.
- */
-#define CAN_WEAR(obj, part)	(IS_SET((obj)->wear_flags,  (part)))
-#define IS_OBJ_STAT(obj, stat)	(IS_SET((obj)->extra_flags, (stat)))
-#define IS_WEAPON_STAT(obj,stat)(IS_SET((obj)->value[4],(stat)))
-#define WEIGHT_MULT(obj)	((obj)->item_type == ITEM_CONTAINER ? \
-	(obj)->value[4] : 100)
-
-#define	IS_QUESTOR(ch)     (!IS_NPC(ch) && IS_SET((ch)->act, PLR_QUESTOR) && \
-							(ch)->pcdata->questgiver != 0 )
-
-/*
- * Description macros.
- */
-#define PERS(ch, looker)	( can_see( looker, (ch) ) ?		\
-				( IS_NPC(ch) ? (ch)->short_descr	\
-				: (ch)->name ) : IS_IMMORTAL(ch) ? "an Immortal" : "someone" )
-
-/*
- * Structure for a social in the socials table.
- */
-struct social_type
-{
-	const char *name;
-	const char *char_no_arg;
-	const char *others_no_arg;
-	const char *char_found;
-	const char *others_found;
-	const char *vict_found;
-	const char *char_not_found;
-	const char *char_auto;
-	const char *others_auto;
-	SOCIAL_DATA *next, *prev, *next_hash;
-	bool valid;
-};
-
-/*
- * Global constants.
- */
-extern const struct str_app_type str_app[26];
-extern const struct int_app_type int_app[26];
-extern const struct wis_app_type wis_app[26];
-extern const struct dex_app_type dex_app[26];
-extern const struct con_app_type con_app[26];
-
-extern const struct weapon_type weapon_table[];
-extern const struct item_type item_table[];
-extern const struct wiznet_type wiznet_table[];
-extern const struct attack_type attack_table[];
-extern const struct spec_type spec_table[];
-extern const struct liq_type liq_table[];
+#include "macro.h"
 
 /*
  * Global variables.
  */
 #include "globals.h"
 
+#include "proto.h"
+
 /*
  * The crypt(3) function is not available on some operating systems.
  * In particular, the U.S. Government prohibits its export from the
  *   United States to foreign countries.
- * Turn on NOCRYPT to keep passwords in plain text.
  */
 #if	defined(NOCRYPT)
 #define crypt(s1, s2)	(s1)
@@ -2483,22 +146,26 @@
  * Then we close it whenever we need to open a file (e.g. a save file).
  */
 
-#define PLAYER_DIR      "../player/"	/* Player files */
-#define GOD_DIR         "../gods/"	/* list of gods */
-#define DATA_DIR        "../data/"
-#define TEMP_FILE	"../player/romtmp"
-#if !defined(WIN32)
-#define NULL_FILE	"/dev/null"	/* To reserve one stream */
+#if defined(WIN32)
+#define DIR_SYM     "\\"
+#define NULL_FILE   "nul"
 #else
-#define NULL_FILE   "NUL"
-#define WIN32_DIR   "../win32/"
+#define DIR_SYM     "/"
+#define NULL_FILE	"/dev/null"	/* To reserve one stream */
 #endif
 
-#define AREA_LIST       "area.lst"	/* List of areas */
-#define BUG_FILE        "bugs.txt"	/* For 'bug' and bug() */
-#define TYPO_FILE       "typos.txt"	/* For 'typo' */
-#define SHUTDOWN_FILE   "shutdown.txt"	/* For 'shutdown' */
-#define HELP_FILE       "help.are"
+#define PLAYER_DIR      ".."DIR_SYM"player"DIR_SYM	/* Player files */
+#define DATA_DIR        ".."DIR_SYM"data"DIR_SYM
+#define AREA_DIR	    ".."DIR_SYM"area"DIR_SYM
+#define BIN_DIR         ".."DIR_SYM"bin"DIR_SYM
+#define LOG_DIR         ".."DIR_SYM"log"DIR_SYM
+#define NOTE_DIR  	    ".."DIR_SYM"notes"DIR_SYM
+
+#define AREA_LIST       AREA_DIR "area.lst"	/* List of areas */
+#define BUG_FILE        DATA_DIR "bugs.txt"	/* For 'bug' and bug() */
+#define TYPO_FILE       DATA_DIR "typos.txt"	/* For 'typo' */
+#define SHUTDOWN_FILE   DATA_DIR "shutdown.txt"	/* For 'shutdown' */
+#define HELP_FILE       AREA_DIR "help.are"
 #define BAN_FILE	    DATA_DIR "ban.dat"
 #define MUSIC_FILE	    DATA_DIR "music.dat"
 #define DISABLED_FILE	DATA_DIR "disabled.dat"	/* disabled commands */
@@ -2514,110 +181,14 @@
 #define SOCIAL_FILE     DATA_DIR "social.dat"
 #define CORPSE_FILE     DATA_DIR "corpses.dat"
 #define PIT_FILE        DATA_DIR "pit.dat"
-#define BANK_FILE       DATA_DIR "bank.dat"
 #define DEITY_FILE      DATA_DIR "deity.dat"
 #define WPWD_FILE       DATA_DIR "webpass.dat"
 #define MBR_FILE        DATA_DIR "mbr.dat"
-
-#include "proto.h"
-
-/*****************************************************************************
- *                                    OLC                                    *
- *****************************************************************************/
-
-/*
- * Object defined in limbo.are
- * Used in save.c to load objects that don't exist.
- */
-#define OBJ_VNUM_DUMMY	30
-#define MOB_VNUM_DUMMY	30
-
-#define NO_FLAG  -99
-
-/*
- * Area flags.
- */
-#define         AREA_NONE       0
-#define         AREA_CHANGED    (BIT_A)	/* Area has been modified. */
-#define         AREA_ADDED      (BIT_B)	/* Area has been added to. */
-#define         AREA_LOADING    (BIT_C)	/* Used for counting in db.c */
-#define    AREA_PLAYER_HOMES           (BIT_D)
-#define    AREA_CLOSED                 (BIT_E)
-
-#define MAX_DIR	6
-
-#define AREA_VERSION    1
-
-/*
- * Global Constants
- */
-extern char *const dir_name[];
-extern const int rev_dir[];		/* int - ROM OLC */
-
-/*
- * Global variables
- */
-extern AREA_DATA *area_first;
-extern AREA_DATA *area_last;
-
-extern int top_affect;
-extern int top_area;
-extern int top_ed;
-extern int top_exit;
-extern int top_help;
-extern int top_mob_index;
-extern int top_obj_index;
-extern int top_reset;
-extern int top_room;
-extern int top_explored;
-extern int top_shop;
-
-extern vnum_t top_vnum_mob;
-extern vnum_t top_vnum_obj;
-extern vnum_t top_vnum_room;
-
-extern MOB_INDEX_DATA *mob_index_hash[MAX_KEY_HASH];
-extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH];
-extern ROOM_INDEX_DATA *room_index_hash[MAX_KEY_HASH];
-
-extern CORPSE_DATA *corpse_first;
-extern CORPSE_DATA *corpse_last;
-
-#define STRING_END      2
-#define STRING_FOUND    1
-#define STRING_NONE     0
-
-#define alloc_mem(result, type, number)                            \
-do                                                                \
-{                                                                \
-    if (!((result) = (type *) calloc ((number), sizeof(type))))    \
-    {                                                            \
-    perror("malloc failure");                                \
-    logf( "Malloc failure @ %s:%d\n", __FILE__, __LINE__ ); \
-    abort();                                            \
-    }                                                            \
-} while(0)
-
-#define realloc_mem(result,type,number)                                        \
-do                                                                            \
-{                                                                            \
-    if (!((result) = (type *) realloc ((result), sizeof(type) * (number)))) \
-    {                                                                        \
-    perror("realloc failure");                                            \
-    logf( "Realloc failure @ %s:%d\n", __FILE__, __LINE__ );            \
-    abort();                                                        \
-    }                                                                        \
-} while(0)
-
-#define free_mem(point)                                                         \
-do                                                                                \
-{                                                                                \
-  if (!(point))                                                                    \
-  {                                                                                \
-    bugf("Freeing null pointer %s:%d", __FILE__, __LINE__ );               \
-  }                                                                                \
-  else free((void *)point);                                                                \
-  point = NULL;                                                                    \
-} while(0)
+#define	CHANNEL_FILE	DATA_DIR "channels.dat"
+#define MUD_FILE        DATA_DIR "mud.dat"
+#define TIME_FILE	DATA_DIR "time.dat"
+#if !defined(NO_COPYOVER)
+#define COPYOVER_FILE   DATA_DIR "copyover.txt"
+#endif
 
 #endif
Only in src: mob_cmds.c
diff -ur -x config -x o -x rom src/mob_cmds.h new/mob_cmds.h
--- src/mob_cmds.h	Tue May 27 02:46:36 2003
+++ new/mob_cmds.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
@@ -56,7 +56,7 @@
 };
 
 /* the command table itself */
-extern const struct mob_cmd_type mob_cmd_table[];
+EXTERN const struct mob_cmd_type mob_cmd_table[];
 
 /*
  * MOBcommand functions.
Only in src: mob_prog.c
diff -ur -x config -x o -x rom src/multiclass.c new/multiclass.c
--- src/multiclass.c	Tue May 27 02:46:36 2003
+++ new/multiclass.c	Sun Aug 31 19:23:20 2003
@@ -22,14 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 #include "merc.h"
 
 CH_CMD(do_remor)
@@ -80,7 +76,7 @@
 /* Remove high level eq since we're going back to level 1 */
 	for (x = 0; x < MAX_WEAR; x++)
 	{
-		if (get_eq_char(ch, x) != NULL)
+		if (get_eq_char(ch, (wloc_t) x) != NULL)
 		{
 			chprintln(ch,
 					  "Remove all of your eq first. (heal uncurse for cursed items)");
@@ -90,7 +86,7 @@
 
 	if (ch->pcdata->confirm_remort)
 	{
-		if (argument[0] != '\0')
+		if (!IS_NULLSTR(argument))
 		{
 			chprintln(ch, "Remort status removed.");
 			ch->pcdata->confirm_remort = FALSE;
@@ -198,7 +194,7 @@
 		}
 	}
 
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Just type remort.  No argument.");
 		return;
@@ -631,7 +627,7 @@
 /* Simple bonus function for eq levels */
 int lvl_bonus(CHAR_DATA * ch)
 {
-	return maxClass + number_classes(ch);
+	return 1 + number_classes(ch);
 }
 
 /* Returns TRUE if skill number is a race skill 
diff -ur -x config -x o -x rom src/music.c new/music.c
--- src/music.c	Tue May 27 02:46:36 2003
+++ new/music.c	Sun Aug 31 19:23:20 2003
@@ -22,25 +22,27 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
 #include "merc.h"
 #include "music.h"
 #include "recycle.h"
 #include "interp.h"
 
 int channel_songs[MAX_GLOBAL + 1];
-struct song_data song_table[MAX_SONGS];
+
+int song_lookup(const char *name)
+{
+	int i;
+
+	for (i = 0; i < maxSongs; i++)
+		if (is_name(name, song_table[i].name))
+			return i;
+
+	return -1;
+}
 
 void song_update(void)
 {
@@ -53,7 +55,7 @@
 	int i;
 
 	/* do the global song, if any */
-	if (channel_songs[1] >= MAX_SONGS)
+	if (channel_songs[1] >= maxSongs)
 		channel_songs[1] = -1;
 
 	if (channel_songs[1] > -1)
@@ -102,7 +104,7 @@
 		if (obj->item_type != ITEM_JUKEBOX || obj->value[1] < 0)
 			continue;
 
-		if (obj->value[1] >= MAX_SONGS)
+		if (obj->value[1] >= maxSongs)
 		{
 			obj->value[1] = -1;
 			continue;
@@ -154,66 +156,6 @@
 	}
 }
 
-void load_songs(void)
-{
-	FILE *fp;
-	int count = 0, lines, i;
-	char letter;
-
-	/* reset global */
-	for (i = 0; i <= MAX_GLOBAL; i++)
-		channel_songs[i] = -1;
-
-	if ((fp = file_open(MUSIC_FILE, "r")) == NULL)
-	{
-		bug("Couldn't open music file, no songs available.", 0);
-		file_close(fp);
-		return;
-	}
-
-	for (count = 0; count < MAX_SONGS; count++)
-	{
-		letter = fread_letter(fp);
-		if (letter == '#')
-		{
-			if (count < MAX_SONGS)
-				song_table[count].name = NULL;
-			file_close(fp);
-			return;
-		}
-		else
-			ungetc(letter, fp);
-
-		song_table[count].group = fread_string(fp);
-		song_table[count].name = fread_string(fp);
-
-		/* read lyrics */
-		lines = 0;
-
-		for (;;)
-		{
-			letter = fread_letter(fp);
-
-			if (letter == '~')
-			{
-				song_table[count].lines = lines;
-				break;
-			}
-			else
-				ungetc(letter, fp);
-
-			if (lines >= MAX_LINES)
-			{
-				bug("Too many lines in a song -- limit is  %d.", MAX_LINES);
-				break;
-			}
-
-			song_table[count].lyrics[lines] = str_dup(freadline(fp));
-			lines++;
-		}
-	}
-}
-
 CH_CMD(do_play)
 {
 	OBJ_DATA *juke;
@@ -229,7 +171,7 @@
 		if (juke->item_type == ITEM_JUKEBOX && can_see_obj(ch, juke))
 			break;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Play what?");
 		return;
@@ -244,7 +186,6 @@
 	if (!str_cmp(arg, "list"))
 	{
 		BUFFER *buffer;
-		char buf[MAX_STRING_LENGTH];
 		int col = 0;
 		bool artist = FALSE, match = FALSE;
 
@@ -255,35 +196,30 @@
 		if (!str_cmp(arg, "artist"))
 			artist = TRUE;
 
-		if (argument[0] != '\0')
+		if (!IS_NULLSTR(argument))
 			match = TRUE;
 
-		sprintf(buf, "%s has the following songs available:\n\r",
-				juke->short_descr);
-		add_buf(buffer, capitalize(buf));
+		bprintlnf(buffer, "%s has the following songs available:",
+				  juke->short_descr);
 
-		for (i = 0; i < MAX_SONGS; i++)
+		for (i = 0; i < maxSongs; i++)
 		{
-			if (song_table[i].name == NULL)
-				break;
-
 			if (artist &&
 				(!match || !str_prefix(argument, song_table[i].group)))
-				sprintf(buf, "%-39s %-39s\n\r", song_table[i].group,
-						song_table[i].name);
+				bprintlnf(buffer, "%-39s %-39s", song_table[i].group,
+						  song_table[i].name);
 			else if (!artist
 					 && (!match || !str_prefix(argument, song_table[i].name)))
-				sprintf(buf, "%-35s ", song_table[i].name);
+				bprintf(buffer, "%-35s ", song_table[i].name);
 			else
 				continue;
-			add_buf(buffer, buf);
 			if (!artist && ++col % 2 == 0)
-				add_buf(buffer, "\n\r");
+				bprintln(buffer, "");
 		}
 		if (!artist && col % 2 != 0)
-			add_buf(buffer, "\n\r");
+			bprintln(buffer, "");
 
-		page_to_char(buf_string(buffer), ch);
+		sendpage(ch, buf_string(buffer));
 		free_buf(buffer);
 		return;
 	}
@@ -294,7 +230,7 @@
 		global = TRUE;
 	}
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Play what?");
 		return;
@@ -307,18 +243,13 @@
 		return;
 	}
 
-	for (song = 0; song < MAX_SONGS; song++)
+	for (song = 0; song < maxSongs; song++)
 	{
-		if (song_table[song].name == NULL)
-		{
-			chprintln(ch, "That song isn't available.");
-			return;
-		}
 		if (!str_prefix(argument, song_table[song].name))
 			break;
 	}
 
-	if (song >= MAX_SONGS)
+	if (song >= maxSongs)
 	{
 		chprintln(ch, "That song isn't available.");
 		return;
diff -ur -x config -x o -x rom src/music.h new/music.h
--- src/music.h	Tue May 27 02:46:36 2003
+++ new/music.h	Sun Aug 31 19:23:21 2003
@@ -22,14 +22,13 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
 #if !defined(MUSIC_H)
 #define MUSIC_H
 
-#define MAX_SONGS	20
 #define MAX_LINES	100			/* this boils down to about 1k per song */
 #define MAX_GLOBAL	10			/* max songs the global jukebox can hold */
 
@@ -41,9 +40,7 @@
 	int lines;
 };
 
-extern struct song_data song_table[MAX_SONGS];
-
-void song_update args((void));
-void load_songs args((void));
+PROTOTYPE(void song_update, (void));
+EXTERN int channel_songs[MAX_GLOBAL + 1];
 
 #endif
diff -ur -x config -x o -x rom src/nanny.c new/nanny.c
--- src/nanny.c	Tue May 27 02:46:36 2003
+++ new/nanny.c	Sun Aug 31 19:23:20 2003
@@ -22,16 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#if defined(WIN32)
-#include <time.h>
-#endif
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "interp.h"
 #include "telnet.h"
@@ -39,11 +32,9 @@
 #include "lookup.h"
 #include "tables.h"
 
-bool check_playing args((DESCRIPTOR_DATA * d, const char *name));
-bool check_parse_name args((const char *name));
-bool check_reconnect args((DESCRIPTOR_DATA * d, const char *name, bool fConn));
-bool wizlock;					/* Game is wizlocked        */
-bool newlock;					/* Game is newlocked        */
+PROTOTYPE(bool check_playing, (DESCRIPTOR_DATA *, const char *));
+PROTOTYPE(bool check_parse_name, (const char *));
+PROTOTYPE(bool check_reconnect, (DESCRIPTOR_DATA *, const char *, bool));
 
 void handle_con_get_term(DESCRIPTOR_DATA * d, const char *argument)
 {
@@ -52,25 +43,25 @@
 	case 'y':
 	case 'Y':
 		SET_BIT(d->d_flags, DESC_COLOUR);
-		write_to_buffer(d, "{cColour Enabled...{x\n\r", 0);
+		d_println(d, "{cColour Enabled...{x", 0);
 		break;
 	case 'n':
 	case 'N':
 		REMOVE_BIT(d->d_flags, DESC_COLOUR);
-		write_to_buffer(d, "Colour Disabled...\n\r", 0);
+		d_println(d, "Colour Disabled...", 0);
 		break;
 	case 't':
 	case 'T':
-		write_to_buffer(d,
-						FORMATF("\n\rThis text should be " CL_FORMAT2
-								"GREEN" CL_DEFAULT
-								".\n\rThis text should be " CL_FORMAT2 "RED"
-								CL_DEFAULT ".\n\r", CL_BRIGHT, FG_GREEN,
-								CL_BRIGHT, FG_RED), 0);
-		write_to_buffer(d, "\n\rDid you see colour? (Y)es, (N)o, (T)est: ", 0);
+		d_println(d,
+				  FORMATF("\n\rThis text should be " CL_FORMAT2
+						  "GREEN" CL_DEFAULT
+						  ".\n\rThis text should be " CL_FORMAT2 "RED"
+						  CL_DEFAULT ".\n\r", CL_BRIGHT, FG_GREEN,
+						  CL_BRIGHT, FG_RED), 0);
+		d_print(d, "\n\rDid you see colour? (Y)es, (N)o, (T)est: ", 0);
 		return;
 	default:
-		write_to_buffer(d, "Please answer (Y)es, (N)o, (T)est: ", 0);
+		d_print(d, "Please answer (Y)es, (N)o, (T)est: ", 0);
 		return;
 	}
 	show_greeting(d);
@@ -81,9 +72,8 @@
 {
 	CHAR_DATA *ch;
 	bool fOld;
-	char buf[MAX_STRING_LENGTH];
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		close_socket(d);
 		return;
@@ -92,7 +82,7 @@
 	//argument[0] = UPPER (argument[0]);
 	if (!check_parse_name(argument))
 	{
-		write_to_buffer(d, "Illegal name, try another.\n\rName: ", 0);
+		d_print(d, "Illegal name, try another.\n\rName: ", 0);
 		return;
 	}
 
@@ -103,14 +93,14 @@
 	{
 		sprintf(log_buf, "Denying access to %s@%s.", argument, d->host);
 		log_string(log_buf);
-		write_to_buffer(d, "You are denied access.\n\r", 0);
+		d_println(d, "You are denied access.", 0);
 		close_socket(d);
 		return;
 	}
 
 	if (check_ban(d->host, BAN_PERMIT) && !IS_SET(ch->act, PLR_PERMIT))
 	{
-		write_to_buffer(d, "Your site has been banned from this mud.\n\r", 0);
+		d_println(d, "Your site has been banned from this mud.", 0);
 		close_socket(d);
 		return;
 	}
@@ -121,9 +111,9 @@
 	}
 	else
 	{
-		if (wizlock && !IS_IMMORTAL(ch))
+		if (IS_SET(mud_info.mud_flags, MUD_WIZLOCK) && !IS_IMMORTAL(ch))
 		{
-			write_to_buffer(d, "The game is wizlocked.\n\r", 0);
+			d_println(d, "The game is wizlocked.", 0);
 			close_socket(d);
 			return;
 		}
@@ -132,32 +122,29 @@
 	if (fOld)
 	{
 		/* Old player */
-		write_to_buffer(d, "Password: ", 0);
-		write_to_buffer(d, echo_off_str, 0);
+		d_print(d, "Password: ", 0);
+		d_write(d, echo_off_str, 0);
 		d->connected = CON_GET_OLD_PASSWORD;
 		return;
 	}
 	else
 	{
 		/* New player */
-		if (newlock)
+		if (IS_SET(mud_info.mud_flags, MUD_NEWLOCK))
 		{
-			write_to_buffer(d, "The game is newlocked.\n\r", 0);
+			d_println(d, "The game is newlocked.", 0);
 			close_socket(d);
 			return;
 		}
 
 		if (check_ban(d->host, BAN_NEWBIES))
 		{
-			write_to_buffer(d,
-							"New players are not allowed from your site.\n\r",
-							0);
+			d_println(d, "New players are not allowed from your site.", 0);
 			close_socket(d);
 			return;
 		}
 
-		sprintf(buf, "Did I get that right, %s (Y/N)? ", capitalize(argument));
-		write_to_buffer(d, buf, 0);
+		d_printf(d, "Did I get that right, %s (Y/N)? ", capitalize(argument));
 		d->connected = CON_CONFIRM_NEW_NAME;
 		return;
 	}
@@ -167,16 +154,16 @@
 {
 	CHAR_DATA *ch = CH(d);
 
-	write_to_buffer(d, "\n\r", 2);
+	d_println(d, "", 0);
 
 	if (str_casecmp(crypt(argument, ch->pcdata->pwd), ch->pcdata->pwd))
 	{
-		write_to_buffer(d, "Wrong password.\n\r", 0);
+		d_println(d, "Wrong password.", 0);
 		close_socket(d);
 		return;
 	}
 
-	write_to_buffer(d, echo_on_str, 0);
+	d_write(d, echo_on_str, 0);
 
 	if (check_playing(d, ch->name))
 		return;
@@ -218,15 +205,15 @@
 
 			if (str_cmp
 				(ch->name,
-				 d_old->original ? d_old->original->name : d_old->
-				 character->name))
+				 d_old->original ? d_old->original->name : d_old->character->
+				 name))
 				continue;
 
 			close_socket(d_old);
 		}
 		if (check_reconnect(d, ch->name, TRUE))
 			return;
-		write_to_buffer(d, "Reconnect attempt failed.\n\rName: ", 0);
+		d_print(d, "Reconnect attempt failed.\n\rName: ", 0);
 		if (d->character != NULL)
 		{
 			free_char(d->character);
@@ -237,7 +224,7 @@
 
 	case 'n':
 	case 'N':
-		write_to_buffer(d, "Name: ", 0);
+		d_print(d, "Name: ", 0);
 		if (d->character != NULL)
 		{
 			free_char(d->character);
@@ -247,7 +234,7 @@
 		break;
 
 	default:
-		write_to_buffer(d, "Please type Y or N? ", 0);
+		d_print(d, "Please type Y or N? ", 0);
 		break;
 	}
 }
@@ -255,29 +242,26 @@
 void handle_con_confirm_new_name(DESCRIPTOR_DATA * d, const char *argument)
 {
 	CHAR_DATA *ch = CH(d);
-	char buf[MSL];
 
 	switch (*argument)
 	{
 	case 'y':
 	case 'Y':
-		sprintf(buf,
-				"New character.\n\rGive me a password for %s: %s",
-				ch->name, echo_off_str);
-		write_to_buffer(d, buf, 0);
+		d_printf(d, "New character.\n\rGive me a password for %s: ", ch->name);
+		d_write(d, echo_off_str, 0);
 		d->connected = CON_GET_NEW_PASSWORD;
 		break;
 
 	case 'n':
 	case 'N':
-		write_to_buffer(d, "Ok, what IS it, then? ", 0);
+		d_print(d, "Ok, what IS it, then? ", 0);
 		free_char(d->character);
 		d->character = NULL;
 		d->connected = CON_GET_NAME;
 		break;
 
 	default:
-		write_to_buffer(d, "Please type Yes or No? ", 0);
+		d_print(d, "Please type Yes or No? ", 0);
 		break;
 	}
 }
@@ -288,13 +272,13 @@
 	const char *pwdnew;
 	const char *p;
 
-	write_to_buffer(d, "\n\r", 2);
+	d_println(d, "", 0);
 
 	if (strlen(argument) < 5)
 	{
-		write_to_buffer(d,
-						"Password must be at least five characters long.\n\rPassword: ",
-						0);
+		d_print(d,
+				"Password must be at least five characters long.\n\rPassword: ",
+				0);
 		return;
 	}
 
@@ -303,16 +287,14 @@
 	{
 		if (*p == '~')
 		{
-			write_to_buffer(d,
-							"New password not acceptable, try again.\n\rPassword: ",
-							0);
+			d_print(d,
+					"New password not acceptable, try again.\n\rPassword: ", 0);
 			return;
 		}
 	}
 
-	free_string(ch->pcdata->pwd);
-	ch->pcdata->pwd = str_dup(pwdnew);
-	write_to_buffer(d, "Please retype password: ", 0);
+	replace_string(ch->pcdata->pwd, pwdnew);
+	d_print(d, "Please retype password: ", 0);
 	d->connected = CON_CONFIRM_NEW_PASSWORD;
 }
 
@@ -321,26 +303,27 @@
 	CHAR_DATA *ch = CH(d);
 	RACE_DATA *race;
 
-	write_to_buffer(d, "\n\r", 2);
+	d_println(d, "", 0);
 
 	if (str_casecmp(crypt(argument, ch->pcdata->pwd), ch->pcdata->pwd))
 	{
-		write_to_buffer(d, "Passwords don't match.\n\rRetype password: ", 0);
+		d_print(d, "Passwords don't match.\n\rRetype password: ", 0);
 		d->connected = CON_GET_NEW_PASSWORD;
 		return;
 	}
 
-	write_to_buffer(d, echo_on_str, 0);
-	write_to_buffer(d, "The following races are available:\n\r  ", 0);
+	d_write(d, echo_on_str, 0);
+	d_println(d, "The following races are available:", 0);
+	d_print(d, " ", 1);
 	for (race = race_first; race; race = race->next)
 	{
 		if (!race->pc_race)
 			continue;
-		write_to_buffer(d, race->name, 0);
-		write_to_buffer(d, " ", 1);
+		d_print(d, race->name, 0);
+		d_print(d, " ", 1);
 	}
-	write_to_buffer(d, "\n\r", 0);
-	write_to_buffer(d, "What is your race (help for more information)? ", 0);
+	d_println(d, "", 0);
+	d_print(d, "What is your race (help for more information)? ", 0);
 	d->connected = CON_GET_NEW_RACE;
 }
 
@@ -356,12 +339,11 @@
 	if (!str_cmp(arg, "help"))
 	{
 		argument = one_argument(argument, arg);
-		if (argument[0] == '\0')
+		if (IS_NULLSTR(argument))
 			do_function(ch, &do_oldhelp, "race help");
 		else
 			do_function(ch, &do_oldhelp, argument);
-		write_to_buffer(d,
-						"What is your race (help for more information)? ", 0);
+		d_print(d, "What is your race (help for more information)? ", 0);
 		return;
 	}
 
@@ -369,27 +351,24 @@
 
 	if (race == NULL || !race->pc_race)
 	{
-		write_to_buffer(d, "That is not a valid race.\n\r", 0);
-		write_to_buffer(d, "The following races are available:\n\r  ", 0);
+		d_println(d, "That is not a valid race.", 0);
+		d_println(d, "The following races are available:", 0);
+		d_print(d, " ", 1);
 		for (race = race_first; race; race = race->next)
 		{
 			if (!race->pc_race)
 				continue;
-			write_to_buffer(d, race->name, 0);
-			write_to_buffer(d, " ", 1);
+			d_print(d, race->name, 0);
+			d_print(d, " ", 1);
 		}
-		write_to_buffer(d, "\n\r", 0);
-		write_to_buffer(d,
-						"What is your race? (help for more information) ", 0);
+		d_println(d, "", 0);
+		d_print(d, "What is your race? (help for more information) ", 0);
 		return;
 	}
 
 	if (IS_SET(ch->act, PLR_REMORT) && ch->race != race)
 	{
-		char buf[MSL];
-
-		sprintf(buf, "You are now a %s forever.\n\r", ch->race->name);
-		write_to_buffer(d, buf, 0);
+		d_printlnf(d, "You are now a %s forever.", ch->race->name);
 		ch->pcdata->stay_race = TRUE;
 	}
 
@@ -415,7 +394,7 @@
 	ch->pcdata->points = race->points;
 	ch->size = race->size;
 
-	write_to_buffer(d, "What is your sex (M/F)? ", 0);
+	d_print(d, "What is your sex (M/F)? ", 0);
 	d->connected = CON_GET_NEW_SEX;
 }
 
@@ -438,7 +417,7 @@
 		ch->pcdata->true_sex = SEX_FEMALE;
 		break;
 	default:
-		write_to_buffer(d, "That's not a sex.\n\rWhat IS your sex? ", 0);
+		d_print(d, "That's not a sex.\n\rWhat IS your sex? ", 0);
 		return;
 	}
 
@@ -453,7 +432,7 @@
 		strcat(buf, class_table[iClass].name);
 	}
 	strcat(buf, "]: ");
-	write_to_buffer(d, buf, 0);
+	d_print(d, buf, 0);
 	d->connected = CON_GET_NEW_CLASS;
 }
 
@@ -464,17 +443,14 @@
 
 	if (iClass == -1)
 	{
-		write_to_buffer(d, "That's not a class.\n\rWhat IS your class? ", 0);
+		d_print(d, "That's not a class.\n\rWhat IS your class? ", 0);
 		return;
 	}
 	/* check to see if person is already a class */
 	if (is_class(ch, iClass))
 	{
-		char buf[MSL];
-
-		sprintf(buf, "You are already part %s. Try another!\n\r",
-				class_table[iClass].name);
-		write_to_buffer(d, buf, 0);
+		d_printlnf(d, "You are already part %s. Try another!",
+				   class_table[iClass].name);
 		return;
 	}
 
@@ -490,25 +466,25 @@
 		wiznet("Newbie alert!  $N sighted.", ch, NULL, WIZ_NEWBIE, 0, 0);
 		wiznet(log_buf, NULL, NULL, WIZ_SITES, 0, get_trust(ch));
 
-		write_to_buffer(d, "\n\r", 2);
-		write_to_buffer(d, "You may be good, neutral, or evil.\n\r", 0);
-		write_to_buffer(d, "Which alignment (G/N/E)? ", 0);
+		d_println(d, "", 0);
+		d_println(d, "You may be good, neutral, or evil.", 0);
+		d_print(d, "Which alignment (G/N/E)? ", 0);
 		d->connected = CON_GET_ALIGNMENT;
 	}
 	else
 	{
 		/* send remorts to customization */
-		write_to_buffer(d, "\n\r", 2);
+		d_println(d, "", 0);
 		ch->gen_data = new_gen_data();
 		ch->gen_data->points_chosen = ch->pcdata->points;
 		add_base_groups(ch);
 		ch->pcdata->learned[gsn_recall] =
 			UMAX(50, ch->pcdata->learned[gsn_recall]);
-		write_to_buffer(d, "Do you wish to customize this character?\n\r", 0);
-		write_to_buffer(d,
-						"Customization takes time, but allows a wider range of skills and abilities.\n\r",
-						0);
-		write_to_buffer(d, "Customize (Y/N)? ", 0);
+		d_println(d, "Do you wish to customize this character?", 0);
+		d_println(d,
+				  "Customization takes time, but allows a wider range of skills and abilities.",
+				  0);
+		d_print(d, "Customize (Y/N)? ", 0);
 		d->connected = CON_DEFAULT_CHOICE;
 	}
 }
@@ -516,15 +492,13 @@
 void send_deity_info(DESCRIPTOR_DATA * d)
 {
 	DEITY_DATA *i;
-	char buf[MSL];
 
-	write_to_buffer(d, "\n\rDeities Available:\n\r", 0);
+	d_println(d, "\n\rDeities Available:", 0);
 	for (i = deity_first; i; i = i->next)
 	{
-		sprintf(buf, "\t%-12s : %s\n\r", i->name, i->desc);
-		write_to_buffer(d, buf, 0);
+		d_printlnf(d, "\t%-12s : %s", i->name, i->desc);
 	}
-	write_to_buffer(d, "\n\r", 2);
+	d_println(d, "", 0);
 }
 
 void handle_con_get_alignment(DESCRIPTOR_DATA * d, const char *argument)
@@ -546,13 +520,13 @@
 		ch->alignment = -750;
 		break;
 	default:
-		write_to_buffer(d, "That's not a valid alignment.\n\r", 0);
-		write_to_buffer(d, "Which alignment (G/N/E)? ", 0);
+		d_println(d, "That's not a valid alignment.", 0);
+		d_print(d, "Which alignment (G/N/E)? ", 0);
 		return;
 	}
 
 	send_deity_info(d);
-	write_to_buffer(d, "What deity would you like to worship?", 0);
+	d_print(d, "What deity would you like to worship?", 0);
 	d->connected = CON_GET_DEITY;
 	return;
 }
@@ -577,21 +551,20 @@
 	char arg[MIL];
 	DEITY_DATA *i;
 	CHAR_DATA *ch = CH(d);
-	char buf[MSL];
 
 	one_argument(argument, arg);
 
 	if (!str_cmp(arg, "help"))
 	{
 		argument = one_argument(argument, arg);
-		if (argument[0] == '\0')
+		if (IS_NULLSTR(argument))
 		{
 			send_deity_info(d);
-			write_to_buffer(d, "What deity would you like to worship?\n\r", 0);
+			d_println(d, "What deity would you like to worship?", 0);
 		}
 		else
 			do_function(ch, &do_help, argument);
-		write_to_buffer(d, "What deity would you like to worship?\n\r", 0);
+		d_println(d, "What deity would you like to worship?", 0);
 		return;
 	}
 	i = deity_lookup(argument);
@@ -599,15 +572,14 @@
 	if (i == NULL)
 	{
 		send_deity_info(d);
-		write_to_buffer(d, "What deity would you like to worship?\n\r", 0);
+		d_println(d, "What deity would you like to worship?", 0);
 		return;
 	}
 	ch->deity = i;
-	sprintf(buf, "\n\rYou now worship %s.\n\r", ch->deity->name);
-	write_to_buffer(d, buf, 0);
+	d_printlnf(d, "\n\rYou now worship %s.", ch->deity->name);
 
 	send_timezone_info(d);
-	write_to_buffer(d, "What time zone do you live in?\n\r", 0);
+	d_println(d, "What time zone do you live in?", 0);
 	d->connected = CON_GET_TIMEZONE;
 	return;
 }
@@ -616,7 +588,6 @@
 {
 	int i;
 	char arg[MIL];
-	char buf[MSL];
 	CHAR_DATA *ch = CH(d);
 
 	one_argument(argument, arg);
@@ -624,44 +595,42 @@
 	if (IS_NULLSTR(arg))
 	{
 		send_timezone_info(d);
-		write_to_buffer(d, "What time zone do you live in?\n\r", 0);
+		d_println(d, "What time zone do you live in?", 0);
 		return;
 	}
 	if (!str_cmp(arg, "help"))
 	{
-		write_to_buffer(d,
-						"Time zones around the world are split up into 24 areas,\n\r",
-						0);
-		write_to_buffer(d, "each relating to Greenwich Mean Time (GMT)\n\r", 0);
-		write_to_buffer(d, "What time zone do you live in?\n\r", 0);
+		d_println(d,
+				  "Time zones around the world are split up into 24 areas,", 0);
+		d_println(d, "each relating to Greenwich Mean Time (GMT)", 0);
+		d_println(d, "What time zone do you live in?", 0);
 		return;
 	}
 	i = tzone_lookup(argument);
 
 	if (i == -1)
 	{
-		write_to_buffer(d,
-						"That is not a valid time zone, please enter the full time zone name. (ex. GMT-5)\n\r",
-						0);
-		write_to_buffer(d, "What time zone do you live in?\n\r", 0);
+		d_println(d,
+				  "That is not a valid time zone, please enter the full time zone name. (ex. GMT-5)",
+				  0);
+		d_println(d, "What time zone do you live in?", 0);
 		return;
 	}
 
 	ch->pcdata->timezone = i;
-	sprintf(buf, "Your time zone is now %-6s %-29s (%s)\n\r",
-			tzone_table[i].name, tzone_table[i].zone, str_time(current_time,
-															   i, NULL));
-	write_to_buffer(d, buf, 0);
-	write_to_buffer(d, "\n\r", 0);
+	d_printlnf(d, "Your time zone is now %s %s (%s)",
+			   tzone_table[i].name, tzone_table[i].zone, str_time(current_time,
+																  i, NULL));
+	d_println(d, "", 0);
 
 	group_add(ch, "rom basics", FALSE);
 	add_base_groups(ch);
 	ch->pcdata->learned[gsn_recall] = 50;
-	write_to_buffer(d, "Do you wish to customize this character?\n\r", 0);
-	write_to_buffer(d,
-					"Customization takes time, but allows a wider range of skills and abilities.\n\r",
-					0);
-	write_to_buffer(d, "Customize (Y/N)? ", 0);
+	d_println(d, "Do you wish to customize this character?", 0);
+	d_println(d,
+			  "Customization takes time, but allows a wider range of skills and abilities.",
+			  0);
+	d_print(d, "Customize (Y/N)? ", 0);
 	d->connected = CON_DEFAULT_CHOICE;
 }
 
@@ -671,7 +640,7 @@
 	int i;
 	char buf[MSL];
 
-	write_to_buffer(d, "\n\r", 2);
+	d_println(d, "", 0);
 	switch (argument[0])
 	{
 	case 'y':
@@ -682,7 +651,7 @@
 		list_group_costs(ch);
 		if (!IS_SET(ch->act, PLR_REMORT))	/* too spammy at tier 6 or 7 */
 		{
-			write_to_buffer(d, "You already have the following skills:\n\r", 0);
+			d_println(d, "You already have the following skills:", 0);
 			do_function(ch, &do_skills, "");
 		}
 		do_function(ch, &do_oldhelp, "menu choice");
@@ -691,10 +660,8 @@
 	case 'n':
 	case 'N':
 		add_default_groups(ch);
-		write_to_buffer(d, "\n\r", 2);
-		write_to_buffer(d,
-						"Please pick a weapon from the following choices:\n\r",
-						0);
+		d_println(d, "", 0);
+		d_println(d, "Please pick a weapon from the following choices:", 0);
 		buf[0] = '\0';
 		for (i = 0; weapon_table[i].name != NULL; i++)
 			if (ch->pcdata->learned[*weapon_table[i].gsn] > 0)
@@ -703,11 +670,11 @@
 				strcat(buf, " ");
 			}
 		strcat(buf, "\n\rYour choice? ");
-		write_to_buffer(d, buf, 0);
+		d_print(d, buf, 0);
 		d->connected = CON_PICK_WEAPON;
 		break;
 	default:
-		write_to_buffer(d, "Please answer (Y/N)? ", 0);
+		d_print(d, "Please answer (Y/N)? ", 0);
 		return;
 	}
 }
@@ -718,11 +685,11 @@
 	int i, weapon;
 	char buf[MSL];
 
-	write_to_buffer(d, "\n\r", 2);
+	d_println(d, "", 0);
 	weapon = weapon_lookup(argument);
 	if (weapon == -1 || ch->pcdata->learned[*weapon_table[weapon].gsn] <= 0)
 	{
-		write_to_buffer(d, "That's not a valid selection. Choices are:\n\r", 0);
+		d_println(d, "That's not a valid selection. Choices are:", 0);
 		buf[0] = '\0';
 		for (i = 0; weapon_table[i].name != NULL; i++)
 			if (ch->pcdata->learned[*weapon_table[i].gsn] > 0)
@@ -731,16 +698,16 @@
 				strcat(buf, " ");
 			}
 		strcat(buf, "\n\rYour choice? ");
-		write_to_buffer(d, buf, 0);
+		d_print(d, buf, 0);
 		return;
 	}
 
 	ch->pcdata->learned[*weapon_table[weapon].gsn] =
 		UMAX(40, ch->pcdata->learned[*weapon_table[weapon].gsn]);
-	write_to_buffer(d, "\n\r", 2);
+	d_println(d, "", 0);
 	if (IS_SET(ch->act, PLR_REMORT))
 	{
-		write_to_buffer(d, "Sucessful Remort!\n\r", 0);
+		d_println(d, "Sucessful Remort!", 0);
 		wiznet("Sucessful Remort!  $N sighted.", ch, NULL, 0, 0, 0);
 		REMOVE_BIT(ch->comm, COMM_QUIET);
 		char_from_room(ch);
@@ -789,10 +756,8 @@
 			ch->train = (40 - ch->pcdata->points + 1) / 2;
 		free_gen_data(ch->gen_data);
 		ch->gen_data = NULL;
-		write_to_buffer(d, "\n\r", 2);
-		write_to_buffer(d,
-						"Please pick a weapon from the following choices:\n\r",
-						0);
+		d_println(d, "", 0);
+		d_println(d, "Please pick a weapon from the following choices:", 0);
 		buf[0] = '\0';
 		for (i = 0; weapon_table[i].name != NULL; i++)
 			if (ch->pcdata->learned[*weapon_table[i].gsn] > 0)
@@ -801,7 +766,7 @@
 				strcat(buf, " ");
 			}
 		strcat(buf, "\n\rYour choice? ");
-		write_to_buffer(d, buf, 0);
+		d_print(d, buf, 0);
 		d->connected = CON_PICK_WEAPON;
 		return;
 	}
@@ -817,7 +782,7 @@
 {
 	CHAR_DATA *ch = CH(d);
 
-	write_to_buffer(d, "\n\r", 2);
+	d_println(d, "", 0);
 	do_function(ch, &do_oldhelp, "motd");
 	d->connected = CON_READ_MOTD;
 }
@@ -827,17 +792,14 @@
 	CHAR_DATA *ch = CH(d);
 	char buf[MSL];
 
-	if (ch->pcdata == NULL || ch->pcdata->pwd[0] == '\0')
+	if (ch->pcdata == NULL || IS_NULLSTR(ch->pcdata->pwd))
 	{
-		write_to_buffer(d, "Warning! Null password!\n\r", 0);
-		write_to_buffer(d, "Please report old password with bug.\n\r", 0);
-		write_to_buffer(d,
-						"Type 'password null <new password>' to fix.\n\r", 0);
+		d_println(d, "Warning! Null password!", 0);
+		d_println(d, "Please report old password with bug.", 0);
+		d_println(d, "Type 'password null <new password>' to fix.", 0);
 	}
 
-	write_to_buffer(d,
-					"\n\rWelcome to ROM 2.4.  Please do not feed the mobiles.\n\r",
-					0);
+	d_println(d, "\n\rWelcome to ROM 2.4.  Please do not feed the mobiles.", 0);
 	LINK(ch, char_first, char_last, next, prev);
 	LINK(ch, player_first, player_last, next_player, prev_player);
 	d->connected = CON_PLAYING;
@@ -917,7 +879,7 @@
 	{
 
 	default:
-		bug("Nanny: bad d->connected %d.", d->connected);
+		bugf("Nanny: bad d->connected %d.", d->connected);
 		close_socket(d);
 		return;
 
diff -ur -x config -x o -x rom src/olc.c new/olc.c
--- src/olc.c	Tue May 27 02:46:36 2003
+++ new/olc.c	Sun Aug 31 19:23:20 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /***************************************************************************
@@ -38,21 +38,14 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#if !defined(WIN32)
-#include <unistd.h>
-#endif
 #include "merc.h"
 #include "tables.h"
 #include "olc.h"
 #include "interp.h"
 #include "lookup.h"
 #include "recycle.h"
+#include "music.h"
+#include "tablesave.h"
 
 MOB_INDEX_DATA xMob;
 OBJ_INDEX_DATA xObj;
@@ -70,193 +63,160 @@
 RACE_DATA xRace;
 CLASS_DATA xClass;
 DEITY_DATA xDeity;
+CHANNEL_DATA xChan;
+MUD xMud;
+SONG_DATA xSong;
+
+const struct olc_ed_type olc_ed_table[ED_MAX] = {
+	{"AEdit", "area", ED_AREA, aedit_show, do_aedit, area_olc_comm_table},
+	{"REdit", "room", ED_ROOM, redit_show, do_redit, room_olc_comm_table},
+	{"OEdit", "object", ED_OBJECT, oedit_show, do_oedit, obj_olc_comm_table},
+	{"MEdit", "mobile", ED_MOBILE, medit_show, do_medit, mob_olc_comm_table},
+	{"HEdit", "help", ED_HELP, hedit_show, do_hedit, help_olc_comm_table},
+
+	{"MPEdit", "mobile program", ED_MPCODE, mpedit_show, do_mpedit,
+	 mprog_olc_comm_table},
+	{"OPEdit", "object program", ED_OPCODE, opedit_show, do_opedit,
+	 oprog_olc_comm_table},
+	{"RPEdit", "room program", ED_RPCODE, rpedit_show, do_rpedit,
+	 rprog_olc_comm_table},
+	{"CEdit", "clan", ED_CLAN, cedit_show, do_cedit, clan_olc_comm_table},
+	{"RAEdit", "race", ED_RACE, raedit_show, do_raedit, race_olc_comm_table},
+	{"SEdit", "social", ED_SOCIAL, sedit_show, do_sedit, social_olc_comm_table},
+	{"SKEdit", "skill", ED_SKILL, skedit_show, do_skedit, skill_olc_comm_table},
+	{"MudEdit", "mud", ED_MUD, mudedit_show, do_mudedit, mud_olc_comm_table},
+	{"GREdit", "group", ED_GROUP, gredit_show, do_gredit, group_olc_comm_table},
+	{"DEdit", "deity", ED_DEITY, dedit_show, do_dedit, deity_olc_comm_table},
+	{"CmdEdit", "command", ED_CMD, cmdedit_show, do_cmdedit, cmd_olc_comm_table},
+	{"ClEdit", "class", ED_CLASS, cledit_show, do_cledit, class_olc_comm_table},
+	{"ChanEdit", "channel", ED_CHAN, chanedit_show, do_chanedit,
+	 chan_olc_comm_table},
 
-/* Executed from comm.c.  Minimizes compiling when changes are made. */
-bool run_olc_editor(DESCRIPTOR_DATA * d, char *incomm)
+	{"SongEdit", "song", ED_SONG, songedit_show, do_songedit,
+	 song_olc_comm_table}
+};
+
+OLCED_DATA *olc_lookup(int ed)
+{
+	int i;
+
+	if (ed == ED_NONE)
+		return NULL;
+
+	for (i = 0; i < ED_MAX; i++)
+		if (olc_ed_table[i].ed == ed)
+			return &olc_ed_table[i];
+
+	return NULL;
+}
+
+AREA_DATA *get_olc_area(DESCRIPTOR_DATA * d)
 {
+	if (d->editor == ED_NONE || d->pEdit == NULL)
+		return NULL;
+
 	switch (d->editor)
 	{
 	case ED_AREA:
-		aedit(d->character, incomm);
-		break;
+		return (AREA_DATA *) d->pEdit;
 	case ED_ROOM:
-		redit(d->character, incomm);
-		break;
+		return ((ROOM_INDEX_DATA *) d->pEdit)->area;
 	case ED_OBJECT:
-		oedit(d->character, incomm);
-		break;
+		return ((OBJ_INDEX_DATA *) d->pEdit)->area;
 	case ED_MOBILE:
-		medit(d->character, incomm);
-		break;
+		return ((MOB_INDEX_DATA *) d->pEdit)->area;
 	case ED_MPCODE:
-		mpedit(d->character, incomm);
-		break;
 	case ED_OPCODE:
-		opedit(d->character, incomm);
-		break;
 	case ED_RPCODE:
-		rpedit(d->character, incomm);
-		break;
-	case ED_HELP:
-		hedit(d->character, incomm);
-		break;
-	case ED_SOCIAL:
-		sedit(d->character, incomm);
-		break;
-	case ED_CLAN:
-		cedit(d->character, incomm);
-		break;
-	case ED_CMD:
-		cmdedit(d->character, incomm);
-		break;
-	case ED_SKILL:
-		skedit(d->character, incomm);
-		break;
-	case ED_GROUP:
-		gredit(d->character, incomm);
-		break;
-	case ED_RACE:
-		raedit(d->character, incomm);
-		break;
-	case ED_CLASS:
-		cledit(d->character, incomm);
-		break;
-	case ED_DEITY:
-		dedit(d->character, incomm);
-		break;
+		return ((PROG_CODE *) d->pEdit)->area;
 	default:
-		return FALSE;
+		return NULL;
 	}
-	return TRUE;
 }
 
-char *olc_ed_name(CHAR_DATA * ch)
+void olcedit(CHAR_DATA * ch, const char *argument, OLCED_DATA * table)
 {
-	static char buf[10];
+	AREA_DATA *pArea;
 
-	buf[0] = '\0';
-	switch (ch->desc->editor)
+	pArea = get_olc_area(ch->desc);
+
+	if (pArea && !IS_BUILDER(ch, pArea))
 	{
-	case ED_AREA:
-		sprintf(buf, "AEdit");
-		break;
-	case ED_ROOM:
-		sprintf(buf, "REdit");
-		break;
-	case ED_OBJECT:
-		sprintf(buf, "OEdit");
-		break;
-	case ED_MOBILE:
-		sprintf(buf, "MEdit");
-		break;
-	case ED_MPCODE:
-		sprintf(buf, "MPEdit");
-		break;
-	case ED_OPCODE:
-		sprintf(buf, "OPEdit");
-		break;
-	case ED_RPCODE:
-		sprintf(buf, "RPEdit");
-		break;
-	case ED_HELP:
-		sprintf(buf, "HEdit");
-		break;
-	case ED_SOCIAL:
-		sprintf(buf, "sEdit");
-		break;
-	case ED_CLAN:
-		sprintf(buf, "cEdit");
-		break;
-	case ED_CMD:
-		sprintf(buf, "cmdEdit");
-		break;
-	case ED_SKILL:
-		sprintf(buf, "skEdit");
-		break;
-	case ED_GROUP:
-		sprintf(buf, "grEdit");
-		break;
-	case ED_RACE:
-		sprintf(buf, "raEdit");
-		break;
-	case ED_CLASS:
-		sprintf(buf, "clEdit");
-		break;
-	case ED_DEITY:
-		strcpy(buf, "DEdit");
-		break;
-	default:
-		sprintf(buf, " ");
-		break;
+		chprintlnf(ch, "%s:  Insufficient security to modify %s.", table->name,
+				   table->longname);
+		edit_done(ch);
+		return;
 	}
-	return buf;
+
+	if (!str_cmp(argument, "done"))
+	{
+		edit_done(ch);
+		return;
+	}
+
+	if (emptystring(argument))
+	{
+		if (table->show != NULL)
+			(*table->show) (ch, argument);
+		return;
+	}
+
+	if (!table->table || !process_olc_command(ch, argument, table->table))
+		interpret(ch, argument);
+	return;
+}
+
+bool run_olc_editor(DESCRIPTOR_DATA * d, char *incomm)
+{
+	OLCED_DATA *ed;
+
+	if ((ed = olc_lookup(d->editor)) == NULL)
+		return FALSE;
+
+	olcedit(CH(d), incomm, ed);
+	return TRUE;
+}
+
+OLC_FUN *get_olc_show(int editor)
+{
+	OLCED_DATA *ed;
+
+	if ((ed = olc_lookup(editor)) == NULL)
+		return NULL;
+
+	return ed->show;
+}
+
+const char *olc_ed_name(DESCRIPTOR_DATA * d)
+{
+	OLCED_DATA *ed;
+
+	if (!d)
+		return &str_empty[0];
+
+	if ((ed = olc_lookup(d->editor)) == NULL)
+		return &str_empty[0];
+
+	return ed->name;
 }
 
-char *olc_ed_name_long(CHAR_DATA * ch)
+const char *olc_ed_name_long(CHAR_DATA * ch)
 {
-	static char buf[50];
+	OLCED_DATA *ed;
 
 	if (!ch->desc)
 		return "Switched";
 
-	buf[0] = '\0';
-	switch (ch->desc->editor)
-	{
-	case ED_AREA:
-		sprintf(buf, "area");
-		break;
-	case ED_ROOM:
-		sprintf(buf, "room");
-		break;
-	case ED_OBJECT:
-		sprintf(buf, "object");
-		break;
-	case ED_MOBILE:
-		sprintf(buf, "mobile");
-		break;
-	case ED_MPCODE:
-		sprintf(buf, "mobile program");
-		break;
-	case ED_OPCODE:
-		sprintf(buf, "object program");
-		break;
-	case ED_RPCODE:
-		sprintf(buf, "room program");
-		break;
-	case ED_HELP:
-		sprintf(buf, "help");
-		break;
-	case ED_SOCIAL:
-		sprintf(buf, "social");
-		break;
-	case ED_CLAN:
-		sprintf(buf, "clan");
-		break;
-	case ED_CMD:
-		sprintf(buf, "command");
-		break;
-	case ED_SKILL:
-		sprintf(buf, "skill");
-		break;
-	case ED_GROUP:
-		sprintf(buf, "group");
-		break;
-	case ED_RACE:
-		sprintf(buf, "race");
-		break;
-	case ED_CLASS:
-		sprintf(buf, "class");
-		break;
-	case ED_DEITY:
-		sprintf(buf, "deity");
-		break;
-	default:
-		break;
-	}
-	return buf;
+	if (IS_NPC(ch))
+		return &str_empty[0];
+
+	if ((ed = olc_lookup(ch->desc->editor)) == NULL)
+		return &str_empty[0];
+
+	return ed->longname;
 }
 
-char *olc_ed_vnum(CHAR_DATA * ch)
+char *olc_ed_vnum(DESCRIPTOR_DATA * d)
 {
 	AREA_DATA *pArea;
 	ROOM_INDEX_DATA *pRoom;
@@ -274,75 +234,88 @@
 	RACE_DATA *pRace;
 	CLASS_DATA *pClass;
 	DEITY_DATA *pDeity;
+	CHANNEL_DATA *pChan;
+	SONG_DATA *pSong;
 	static char buf[MIL];
 
 	buf[0] = '\0';
-	switch (ch->desc->editor)
+	switch (d->editor)
 	{
 	case ED_AREA:
-		pArea = (AREA_DATA *) ch->desc->pEdit;
+		pArea = (AREA_DATA *) d->pEdit;
 		sprintf(buf, "%d", pArea ? pArea->vnum : 0);
 		break;
 	case ED_ROOM:
-		pRoom = ch->in_room;
+		pRoom = CH(d)->in_room;
 		sprintf(buf, "%ld", pRoom ? pRoom->vnum : 0);
 		break;
 	case ED_OBJECT:
-		pObj = (OBJ_INDEX_DATA *) ch->desc->pEdit;
+		pObj = (OBJ_INDEX_DATA *) d->pEdit;
 		sprintf(buf, "%ld", pObj ? pObj->vnum : 0);
 		break;
 	case ED_MOBILE:
-		pMob = (MOB_INDEX_DATA *) ch->desc->pEdit;
+		pMob = (MOB_INDEX_DATA *) d->pEdit;
 		sprintf(buf, "%ld", pMob ? pMob->vnum : 0);
 		break;
 	case ED_MPCODE:
-		pMprog = (PROG_CODE *) ch->desc->pEdit;
+		pMprog = (PROG_CODE *) d->pEdit;
 		sprintf(buf, "%ld", pMprog ? pMprog->vnum : 0);
 		break;
 	case ED_OPCODE:
-		pOprog = (PROG_CODE *) ch->desc->pEdit;
+		pOprog = (PROG_CODE *) d->pEdit;
 		sprintf(buf, "%ld", pOprog ? pOprog->vnum : 0);
 		break;
 	case ED_RPCODE:
-		pRprog = (PROG_CODE *) ch->desc->pEdit;
+		pRprog = (PROG_CODE *) d->pEdit;
 		sprintf(buf, "%ld", pRprog ? pRprog->vnum : 0);
 		break;
 	case ED_HELP:
-		pHelp = (HELP_DATA *) ch->desc->pEdit;
+		pHelp = (HELP_DATA *) d->pEdit;
 		sprintf(buf, "%s", pHelp ? pHelp->keyword : "");
 		break;
 	case ED_SOCIAL:
-		pSocial = (SOCIAL_DATA *) ch->desc->pEdit;
+		pSocial = (SOCIAL_DATA *) d->pEdit;
 		sprintf(buf, "%s", pSocial ? pSocial->name : "");
 		break;
 	case ED_CLAN:
-		pClan = (CLAN_DATA *) ch->desc->pEdit;
+		pClan = (CLAN_DATA *) d->pEdit;
 		sprintf(buf, "%s", pClan ? pClan->name : "");
 		break;
 	case ED_CMD:
-		pCmd = (CMD_DATA *) ch->desc->pEdit;
+		pCmd = (CMD_DATA *) d->pEdit;
 		sprintf(buf, "%s", pCmd ? pCmd->name : "");
 		break;
 	case ED_SKILL:
-		pSkill = (SKILL_DATA *) ch->desc->pEdit;
+		pSkill = (SKILL_DATA *) d->pEdit;
 		sprintf(buf, "%s", pSkill ? pSkill->name : "");
 		break;
 	case ED_GROUP:
-		pGroup = (GROUP_DATA *) ch->desc->pEdit;
+		pGroup = (GROUP_DATA *) d->pEdit;
 		sprintf(buf, "%s", pGroup ? pGroup->name : "");
 		break;
 	case ED_RACE:
-		pRace = (RACE_DATA *) ch->desc->pEdit;
+		pRace = (RACE_DATA *) d->pEdit;
 		sprintf(buf, "%s", pRace ? pRace->name : "");
 		break;
 	case ED_CLASS:
-		pClass = (CLASS_DATA *) ch->desc->pEdit;
+		pClass = (CLASS_DATA *) d->pEdit;
 		sprintf(buf, "%s", pClass ? pClass->name : "");
 		break;
 	case ED_DEITY:
-		pDeity = (DEITY_DATA *) ch->desc->pEdit;
+		pDeity = (DEITY_DATA *) d->pEdit;
 		sprintf(buf, "%s", pDeity ? pDeity->name : "");
 		break;
+	case ED_CHAN:
+		pChan = (CHANNEL_DATA *) d->pEdit;
+		sprintf(buf, "%s", pChan ? pChan->name : "");
+		break;
+	case ED_SONG:
+		pSong = (SONG_DATA *) d->pEdit;
+		sprintf(buf, "%s", pSong ? pSong->name : "");
+		break;
+	case ED_MUD:
+		strcpy(buf, MUD_NAME);
+		break;
 	default:
 		sprintf(buf, " ");
 		break;
@@ -366,68 +339,31 @@
 	return;
 }
 
-const struct olc_comm_type *get_olc_table(int editor)
-{
-	switch (editor)
-	{
-	case ED_MOBILE:
-		return mob_olc_comm_table;
-	case ED_OBJECT:
-		return obj_olc_comm_table;
-	case ED_ROOM:
-		return room_olc_comm_table;
-	case ED_AREA:
-		return area_olc_comm_table;
-	case ED_MPCODE:
-		return mprog_olc_comm_table;
-	case ED_OPCODE:
-		return oprog_olc_comm_table;
-	case ED_RPCODE:
-		return rprog_olc_comm_table;
-	case ED_HELP:
-		return help_olc_comm_table;
-	case ED_SOCIAL:
-		return social_olc_comm_table;
-	case ED_CLAN:
-		return clan_olc_comm_table;
-	case ED_CMD:
-		return cmd_olc_comm_table;
-	case ED_SKILL:
-		return skill_olc_comm_table;
-	case ED_GROUP:
-		return group_olc_comm_table;
-	case ED_RACE:
-		return race_olc_comm_table;
-	case ED_CLASS:
-		return class_olc_comm_table;
-	case ED_DEITY:
-		return deity_olc_comm_table;
-	}
-	return NULL;
-}
-
-void show_olc_cmds(CHAR_DATA * ch)
+/*****************************************************************************
+ Name:		show_commands
+ Purpose:	Display all olc commands.
+ Called by:	olc interpreters.
+ ****************************************************************************/
+bool show_commands(CHAR_DATA * ch, char *argument)
 {
 	char buf[MSL];
 	char buf1[MSL];
 	int cmd;
 	int col;
-	const struct olc_comm_type *table;
+	OLCED_DATA *ed;
 
 	buf1[0] = '\0';
 	col = 0;
 
-	table = get_olc_table(ch->desc->editor);
-
-	if (table == NULL)
+	if ((ed = olc_lookup(ch->desc->editor)) == NULL || ed->table == NULL)
 	{
 		bugf("table NULL, editor %d", ch->desc->editor);
-		return;
+		return FALSE;
 	}
 
-	for (cmd = 0; table[cmd].name != NULL; cmd++)
+	for (cmd = 0; ed->table[cmd].name != NULL; cmd++)
 	{
-		sprintf(buf, "%-15.15s", table[cmd].name);
+		sprintf(buf, "%-15.15s", ed->table[cmd].name);
 		strcat(buf1, buf);
 		if (++col % 5 == 0)
 			strcat(buf1, "\n\r");
@@ -437,17 +373,6 @@
 		strcat(buf1, "\n\r");
 
 	chprint(ch, buf1);
-	return;
-}
-
-/*****************************************************************************
- Name:		show_commands
- Purpose:	Display all olc commands.
- Called by:	olc interpreters.
- ****************************************************************************/
-bool show_commands(CHAR_DATA * ch, char *argument)
-{
-	show_olc_cmds(ch);
 	return FALSE;
 }
 
@@ -455,381 +380,446 @@
  *                           Interpreter Tables.                             *
  *****************************************************************************/
 const struct olc_comm_type mob_olc_comm_table[] = {
-	{"name", (void *) &xMob.player_name, olced_str, NULL},
-	{"short", (void *) &xMob.short_descr, olced_str, NULL},
-	{"long", (void *) &xMob.long_descr, olced_str_line, NULL},
-	{"desc", (void *) &xMob.description, olced_desc, NULL},
+	{"name", (void *) &xMob.player_name, olced_str, NULL, NULL},
+	{"short", (void *) &xMob.short_descr, olced_str, NULL, NULL},
+	{"long", (void *) &xMob.long_descr, olced_str, (const void *) 1, NULL},
+	{"desc", (void *) &xMob.description, olced_desc, NULL, NULL},
 
 	{"level", (void *) &xMob.level, olced_number,
-	 (const void *) validate_level},
+	 NULL, validate_level},
 	{"align", (void *) &xMob.alignment, olced_number,
-	 (const void *) validate_align},
-	{"group", (void *) &xMob.group, olced_olded, (const void *) medit_group},
-	{"imm", (void *) &xMob.imm_flags, olced_flag, (const void *) imm_flags},
-	{"res", (void *) &xMob.res_flags, olced_flag, (const void *) res_flags},
-	{"vuln", (void *) &xMob.vuln_flags, olced_flag, (const void *) vuln_flags},
-	{"act", (void *) &xMob.act, olced_flag, (const void *) act_flags},
+	 NULL, validate_align},
+
+	{"group", (void *) &xMob.group, olced_olded, (const void *) medit_group,
+	 NULL},
+	{"imm", (void *) &xMob.imm_flags, olced_flag, (const void *) imm_flags,
+	 NULL},
+	{"res", (void *) &xMob.res_flags, olced_flag, (const void *) res_flags,
+	 NULL},
+	{"vuln", (void *) &xMob.vuln_flags, olced_flag, (const void *) vuln_flags,
+	 NULL},
+	{"act", (void *) &xMob.act, olced_flag, (const void *) act_flags, NULL},
 
 	{"affect", (void *) &xMob.affected_by, olced_flag,
-	 (const void *) affect_flags},
-	{"off", (void *) &xMob.off_flags, olced_flag, (const void *) off_flags},
-	{"form", (void *) &xMob.form, olced_flag, (const void *) form_flags},
-	{"parts", (void *) &xMob.parts, olced_flag, (const void *) part_flags},
-	{"shop", (void *) &xMob, olced_shop, NULL},
-	{"create", NULL, olced_olded, (const void *) medit_create},
-	{"delete", NULL, olced_olded, (const void *) medit_delete},
-	{"material", (void *) &xMob.material, olced_str, NULL},
-	{"addprog", NULL, olced_olded, (const void *) medit_addmprog},
-	{"delprog", NULL, olced_olded, (const void *) medit_delmprog},
-	{"spec", (void *) &xMob.spec_fun, olced_spec, NULL},
-	{"sex", (void *) &xMob.sex, olced_flag, (const void *) sex_flags},
-	{"size", (void *) &xMob.size, olced_flag, (const void *) size_flags},
+	 (const void *) affect_flags, NULL},
+	{"off", (void *) &xMob.off_flags, olced_flag, (const void *) off_flags, NULL},
+	{"form", (void *) &xMob.form, olced_flag, (const void *) form_flags, NULL},
+	{"parts", (void *) &xMob.parts, olced_flag, (const void *) part_flags, NULL},
+	{"shop", (void *) &xMob, olced_shop, NULL, NULL},
+	{"create", NULL, olced_olded, (const void *) medit_create, NULL},
+	{"delete", NULL, olced_olded, (const void *) medit_delete, NULL},
+	{"material", (void *) &xMob.material, olced_str, NULL, NULL},
+
+	{"addprog", (void *) &xMob.first_mprog, olced_addprog,
+	 (const void *) &xMob.last_mprog, NULL},
+	{"delprog", (void *) &xMob.first_mprog, olced_delprog,
+	 (const void *) &xMob.last_mprog, NULL},
+	{"spec", (void *) &xMob.spec_fun, olced_spec, NULL, NULL},
+	{"sex", (void *) &xMob.sex, olced_flag, (const void *) sex_flags, NULL},
+	{"size", (void *) &xMob.size, olced_flag, (const void *) size_flags, NULL},
 
 	{"startpos", (void *) &xMob.start_pos, olced_flag,
-	 (const void *) position_flags},
+	 (const void *) position_flags, NULL},
 	{"defaultpos", (void *) &xMob.default_pos, olced_flag,
-	 (const void *) position_flags},
-	{"autoeasy", NULL, olced_olded, (const void *) medit_autoeasy},
-	{"autoset", NULL, olced_olded, (const void *) medit_autoset},
-	{"autohard", NULL, olced_olded, (const void *) medit_autohard},
+	 (const void *) position_flags, NULL},
+	{"autoeasy", NULL, olced_olded, (const void *) medit_autoeasy, NULL},
+	{"autoset", NULL, olced_olded, (const void *) medit_autoset, NULL},
+	{"autohard", NULL, olced_olded, (const void *) medit_autohard, NULL},
 	{"damtype", (void *) &xMob.dam_type, olced_poslookup,
-	 (const void *) attack_lookup},
-	{"race", (void *) &xMob, olced_race, NULL},
-	{"armor", (void *) &xMob, olced_ac, NULL},
-	{"hitdice", (void *) &xMob.hit[0], olced_dice, NULL},
-	{"manadice", (void *) &xMob.mana[0], olced_dice, NULL},
-	{"damdice", (void *) &xMob.damage[0], olced_dice, NULL},
-	{"hitroll", (void *) &xMob.hitroll, olced_number, NULL},
-	{"wealth", (void *) &xMob.wealth, olced_number_long, NULL},
-	{"show", NULL, olced_olded, (const void *) medit_show},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	 (const void *) attack_lookup, NULL},
+	{"race", (void *) &xMob, olced_race, NULL, NULL},
+	{"armor", (void *) &xMob, olced_ac, NULL, NULL},
+	{"hitdice", (void *) &xMob.hit[0], olced_dice, NULL, NULL},
+	{"manadice", (void *) &xMob.mana[0], olced_dice, NULL, NULL},
+	{"damdice", (void *) &xMob.damage[0], olced_dice, NULL, NULL},
+	{"hitroll", (void *) &xMob.hitroll, olced_number, NULL, NULL},
+	{"wealth", (void *) &xMob.wealth, olced_number_long, NULL, NULL},
+	{"show", NULL, olced_olded, (const void *) medit_show, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type obj_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) oedit_show},
-	{"create", NULL, olced_olded, (const void *) oedit_create},
-	{"name", (void *) &xObj.name, olced_str, NULL},
-	{"short", (void *) &xObj.short_descr, olced_str, NULL},
-	{"long", (void *) &xObj.description, olced_str, NULL},
-	{"addaffect", NULL, olced_olded, (const void *) oedit_addaffect},
-	{"addapply", NULL, olced_olded, (const void *) oedit_addapply},
-	{"delaffect", NULL, olced_olded, (const void *) oedit_delaffect},
-	{"autoweapon", NULL, olced_olded, (const void *) oedit_autoweapon},
-	{"autoarmor", NULL, olced_olded, (const void *) oedit_autoarmor},
-	{"v0", NULL, olced_value, (const void *) 0},
-	{"v1", NULL, olced_value, (const void *) 1},
-	{"v2", NULL, olced_value, (const void *) 2},
-	{"v3", NULL, olced_value, (const void *) 3},
-	{"v4", NULL, olced_value, (const void *) 4},
-	{"material", (void *) &xObj.material, olced_str, NULL},
-	{"weight", (void *) &xObj.weight, olced_number, NULL},
-	{"cost", (void *) &xObj.cost, olced_number_long, NULL},
+	{"show", NULL, olced_olded, (const void *) oedit_show, NULL},
+	{"create", NULL, olced_olded, (const void *) oedit_create, NULL},
+	{"name", (void *) &xObj.name, olced_str, NULL, NULL},
+	{"short", (void *) &xObj.short_descr, olced_str, NULL, NULL},
+	{"long", (void *) &xObj.description, olced_str, NULL, NULL},
+	{"addaffect", NULL, olced_olded, (const void *) oedit_addaffect, NULL},
+	{"addapply", NULL, olced_olded, (const void *) oedit_addapply, NULL},
+	{"delaffect", NULL, olced_olded, (const void *) oedit_delaffect, NULL},
+	{"autoweapon", NULL, olced_olded, (const void *) oedit_autoweapon, NULL},
+	{"autoarmor", NULL, olced_olded, (const void *) oedit_autoarmor, NULL},
+	{"v0", NULL, olced_value, (const void *) 0, NULL},
+	{"v1", NULL, olced_value, (const void *) 1, NULL},
+	{"v2", NULL, olced_value, (const void *) 2, NULL},
+	{"v3", NULL, olced_value, (const void *) 3, NULL},
+	{"v4", NULL, olced_value, (const void *) 4, NULL},
+	{"material", (void *) &xObj.material, olced_str, NULL, NULL},
+	{"weight", (void *) &xObj.weight, olced_number, NULL, NULL},
+	{"cost", (void *) &xObj.cost, olced_number_long, NULL, NULL},
 
 	{"ed", (void *) &xObj.first_extra_descr, olced_ed,
-	 (const void *) &xObj.last_extra_descr},
-	{"delete", NULL, olced_olded, (const void *) oedit_delete},
+	 (const void *) &xObj.last_extra_descr, NULL},
+	{"delete", NULL, olced_olded, (const void *) oedit_delete, NULL},
 
 	{"extra", (void *) &xObj.extra_flags, olced_flag,
-	 (const void *) extra_flags},
+	 (const void *) extra_flags, NULL},
 	{"wear", (void *) &xObj.wear_flags, olced_flag,
-	 (const void *) wear_flags},
-	{"type", (void *) &xObj.item_type, olced_flag, (const void *) type_flags},
+	 (const void *) wear_flags, NULL},
+
+	{"type", (void *) &xObj.item_type, olced_flag,
+	 (const void *) type_flags, NULL},
+
+	{"level", (void *) &xObj.level, olced_number, NULL,
+	 validate_level},
 
-	{"level", (void *) &xObj.level, olced_number,
-	 (const void *) validate_level},
-	{"addprog", NULL, olced_olded, (void *) oedit_addoprog},
-	{"delprog", NULL, olced_olded, (void *) oedit_deloprog},
-	{"condition", (void *) &xObj.condition, olced_number, NULL},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"addprog", (void *) &xObj.first_oprog, olced_addprog,
+	 (const void *) &xObj.last_oprog, NULL},
+	{"delprog", (void *) &xObj.first_oprog, olced_delprog,
+	 (const void *) &xObj.last_oprog, NULL},
+	{"condition", (void *) &xObj.condition, olced_number, NULL, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type room_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) redit_show},
-	{"create", NULL, olced_olded, (const void *) redit_create},
-	{"name", (void *) &xRoom.name, olced_str, NULL},
-	{"desc", (void *) &xRoom.description, olced_desc, NULL},
+	{"show", NULL, olced_olded, (const void *) redit_show, NULL},
+	{"create", NULL, olced_olded, (const void *) redit_create, NULL},
+	{"name", (void *) &xRoom.name, olced_str, NULL, NULL},
+	{"desc", (void *) &xRoom.description, olced_desc, NULL, NULL},
 
 	{"ed", (void *) &xRoom.first_extra_descr, olced_ed,
-	 (const void *) &xRoom.last_extra_descr},
-	{"format", NULL, olced_olded, (const void *) redit_format},
-	{"north", NULL, olced_direction, (const void *) DIR_NORTH},
-	{"south", NULL, olced_direction, (const void *) DIR_SOUTH},
-	{"east", NULL, olced_direction, (const void *) DIR_EAST},
-	{"west", NULL, olced_direction, (const void *) DIR_WEST},
-	{"up", NULL, olced_direction, (const void *) DIR_UP},
-	{"down", NULL, olced_direction, (const void *) DIR_DOWN},
-	{"mreset", NULL, olced_olded, (const void *) redit_mreset},
-	{"oreset", NULL, olced_olded, (const void *) redit_oreset},
-	{"mshow", NULL, olced_olded, (const void *) redit_mshow},
-	{"oshow", NULL, olced_olded, (const void *) redit_oshow},
-	{"clan", NULL, olced_olded, (const void *) redit_clan},
-	{"purge", NULL, olced_docomm, (const void *) do_purge},
-	{"heal", (void *) &xRoom.heal_rate, olced_number, NULL},
-	{"mana", (void *) &xRoom.mana_rate, olced_number, NULL},
-	{"owner", (void *) &xRoom.owner, olced_str, NULL},
-	{"room", (void *) &xRoom.room_flags, olced_flag, (const void *) room_flags},
-	{"olist", NULL, olced_olded, (const void *) redit_olist},
-	{"mlist", NULL, olced_olded, (const void *) redit_mlist},
-	{"rlist", NULL, olced_olded, (const void *) redit_rlist},
+	 (const void *) &xRoom.last_extra_descr, NULL},
+	{"format", NULL, olced_olded, (const void *) redit_format, NULL},
+	{"north", NULL, olced_direction, (const void *) DIR_NORTH, NULL},
+	{"south", NULL, olced_direction, (const void *) DIR_SOUTH, NULL},
+	{"east", NULL, olced_direction, (const void *) DIR_EAST, NULL},
+	{"west", NULL, olced_direction, (const void *) DIR_WEST, NULL},
+	{"up", NULL, olced_direction, (const void *) DIR_UP, NULL},
+	{"down", NULL, olced_direction, (const void *) DIR_DOWN, NULL},
+	{"mreset", NULL, olced_olded, (const void *) redit_mreset, NULL},
+	{"oreset", NULL, olced_olded, (const void *) redit_oreset, NULL},
+	{"mshow", NULL, olced_olded, (const void *) redit_mshow, NULL},
+	{"oshow", NULL, olced_olded, (const void *) redit_oshow, NULL},
+	{"clan", NULL, olced_olded, (const void *) redit_clan, NULL},
+	{"purge", NULL, olced_docomm, (const void *) do_purge, NULL},
+	{"heal", (void *) &xRoom.heal_rate, olced_number, NULL, NULL},
+	{"mana", (void *) &xRoom.mana_rate, olced_number, NULL, NULL},
+	{"owner", (void *) &xRoom.owner, olced_str, NULL, NULL},
+
+	{"room", (void *) &xRoom.room_flags, olced_flag,
+	 (const void *) room_flags, NULL},
+	{"olist", NULL, olced_olded, (const void *) redit_olist, NULL},
+	{"mlist", NULL, olced_olded, (const void *) redit_mlist, NULL},
+	{"rlist", NULL, olced_olded, (const void *) redit_rlist, NULL},
 	{"sector", (void *) &xRoom.sector_type, olced_flag,
-	 (const void *) sector_flags},
-	{"addprog", NULL, olced_olded, (void *) redit_addrprog},
-	{"delprog", NULL, olced_olded, (void *) redit_delrprog},
-	{"delete", NULL, olced_olded, (const void *) redit_delete},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	 (const void *) sector_flags, NULL},
+
+	{"addprog", (void *) &xRoom.first_rprog, olced_addprog,
+	 (const void *) &xRoom.last_rprog, NULL},
+	{"delprog", (void *) &xRoom.first_rprog, olced_delprog,
+	 (const void *) &xRoom.last_rprog, NULL},
+	{"delete", NULL, olced_olded, (const void *) redit_delete, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type area_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) aedit_show},
-	{"create", NULL, olced_olded, (const void *) aedit_create},
-	{"name", (void *) &xArea.name, olced_str, NULL},
-	{"file", NULL, olced_olded, (const void *) aedit_file},
-	{"age", (void *) &xArea.age, olced_number, NULL},
-	{"reset", NULL, olced_olded, (const void *) aedit_reset},
-	{"security", (void *) &xArea.security, olced_number, NULL},
-	{"lvlmsg", (void *) &xArea.lvl_comment, olced_str, NULL},
-	{"minlvl", (void *) &xArea.min_level, olced_number, NULL},
-	{"maxlvl", (void *) &xArea.max_level, olced_number, NULL},
-	{"builder", NULL, olced_olded, (const void *) aedit_builder},
-	{"vnum", NULL, olced_olded, (const void *) aedit_vnum},
-	{"lvnum", NULL, olced_olded, (const void *) aedit_lvnum},
-	{"uvnum", NULL, olced_olded, (const void *) aedit_uvnum},
-	{"credits", (void *) &xArea.credits, olced_str, NULL},
-	{"flag", (void *) &xArea.area_flags, olced_flag, (const void *) area_flags},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"show", NULL, olced_olded, (const void *) aedit_show, NULL},
+	{"create", NULL, olced_olded, (const void *) aedit_create, NULL},
+	{"name", (void *) &xArea.name, olced_str, NULL, NULL},
+	{"file", NULL, olced_olded, (const void *) aedit_file, NULL},
+	{"age", (void *) &xArea.age, olced_number, NULL, NULL},
+	{"reset", NULL, olced_olded, (const void *) aedit_reset, NULL},
+	{"security", (void *) &xArea.security, olced_number, NULL, NULL},
+	{"lvlmsg", (void *) &xArea.lvl_comment, olced_str, NULL, NULL},
+	{"minlvl", (void *) &xArea.min_level, olced_number, NULL, NULL},
+	{"maxlvl", (void *) &xArea.max_level, olced_number, NULL, NULL},
+	{"builder", NULL, olced_olded, (const void *) aedit_builder, NULL},
+	{"vnum", NULL, olced_olded, (const void *) aedit_vnum, NULL},
+	{"lvnum", NULL, olced_olded, (const void *) aedit_lvnum, NULL},
+	{"uvnum", NULL, olced_olded, (const void *) aedit_uvnum, NULL},
+	{"credits", (void *) &xArea.credits, olced_str, NULL, NULL},
+	{"climate", NULL, olced_olded, (const void *) aedit_climate, NULL},
+	{"flag", (void *) &xArea.area_flags, olced_flag,
+	 (const void *) area_flags, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type mprog_olc_comm_table[] = {
-	{"create", NULL, olced_olded, (const void *) mpedit_create},
-	{"code", (void *) &xMProg.code, olced_desc, NULL},
-	{"show", NULL, olced_olded, (const void *) mpedit_show},
-	{"list", NULL, olced_olded, (const void *) mpedit_list},
-	{"delete", NULL, olced_olded, (const void *) mpedit_delete},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"create", NULL, olced_olded, (const void *) mpedit_create, NULL},
+	{"code", (void *) &xMProg.code, olced_desc, NULL, NULL},
+	{"show", NULL, olced_olded, (const void *) mpedit_show, NULL},
+	{"list", NULL, olced_olded, (const void *) mpedit_list, NULL},
+	{"delete", NULL, olced_olded, (const void *) mpedit_delete, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type oprog_olc_comm_table[] = {
-	{"create", NULL, olced_olded, (const void *) opedit_create},
-	{"code", (void *) &xOProg.code, olced_desc, NULL},
-	{"show", NULL, olced_olded, (const void *) opedit_show},
-	{"list", NULL, olced_olded, (const void *) opedit_list},
-	{"delete", NULL, olced_olded, (const void *) opedit_delete},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"create", NULL, olced_olded, (const void *) opedit_create, NULL},
+	{"code", (void *) &xOProg.code, olced_desc, NULL, NULL},
+	{"show", NULL, olced_olded, (const void *) opedit_show, NULL},
+	{"list", NULL, olced_olded, (const void *) opedit_list, NULL},
+	{"delete", NULL, olced_olded, (const void *) opedit_delete, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type rprog_olc_comm_table[] = {
-	{"create", NULL, olced_olded, (const void *) rpedit_create},
-	{"code", (void *) &xRProg.code, olced_desc, NULL},
-	{"show", NULL, olced_olded, (const void *) rpedit_show},
-	{"list", NULL, olced_olded, (const void *) rpedit_list},
-	{"delete", NULL, olced_olded, (const void *) rpedit_delete},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"create", NULL, olced_olded, (const void *) rpedit_create, NULL},
+	{"code", (void *) &xRProg.code, olced_desc, NULL, NULL},
+	{"show", NULL, olced_olded, (const void *) rpedit_show, NULL},
+	{"list", NULL, olced_olded, (const void *) rpedit_list, NULL},
+	{"delete", NULL, olced_olded, (const void *) rpedit_delete, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type help_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) hedit_show},
-	{"make", NULL, olced_olded, (const void *) hedit_new},
-	{"text", (void *) &xHelp.text, olced_desc, NULL},
-
-	{"level", (void *) &xHelp.level, olced_number,
-	 (const void *) validate_level},
-	{"keywords", (void *) &xHelp.keyword, olced_str, NULL},
-	{"delete", NULL, olced_olded, (const void *) hedit_delete},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"show", NULL, olced_olded, (const void *) hedit_show, NULL},
+	{"make", NULL, olced_olded, (const void *) hedit_new, NULL},
+	{"text", (void *) &xHelp.text, olced_desc, NULL, NULL},
+
+	{"level", (void *) &xHelp.level, olced_number, NULL,
+	 validate_level},
+	{"keywords", (void *) &xHelp.keyword, olced_str, NULL, NULL},
+	{"delete", NULL, olced_olded, (const void *) hedit_delete, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type clan_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) cedit_show},
-	{"name", (void *) &xClan.name, olced_str, NULL},
-	{"who", (void *) &xClan.who_name, olced_str, NULL},
-	{"independent", (void *) &xClan.independent, olced_bool, NULL},
-	{"hall", (void *) &xClan.hall, olced_number, NULL},
-	{"delete", NULL, olced_olded, (const void *) cedit_delete},
-	{"create", NULL, olced_olded, (const void *) cedit_create},
-	{"rank", NULL, olced_olded, (const void *) cedit_rank},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"show", NULL, olced_olded, (const void *) cedit_show, NULL},
+	{"name", (void *) &xClan.name, olced_str, NULL, NULL},
+	{"who", (void *) &xClan.who_name, olced_str, NULL, NULL},
+	{"independent", (void *) &xClan.independent, olced_bool, NULL, NULL},
+	{"hall", (void *) &xClan.hall, olced_number, NULL, NULL},
+	{"delete", NULL, olced_olded, (const void *) cedit_delete, NULL},
+	{"create", NULL, olced_olded, (const void *) cedit_create, NULL},
+	{"rank", NULL, olced_olded, (const void *) cedit_rank, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type social_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) sedit_show},
-	{"name", NULL, olced_olded, (const void *) sedit_name},
-	{"create", NULL, olced_olded, (const void *) sedit_create},
-	{"delete", NULL, olced_olded, (const void *) sedit_delete},
-	{"cnoarg", (void *) &xSoc.char_no_arg, olced_str, NULL},
-	{"onoarg", (void *) &xSoc.others_no_arg, olced_str, NULL},
-	{"cfound", (void *) &xSoc.char_found, olced_str, NULL},
-	{"ofound", (void *) &xSoc.others_found, olced_str, NULL},
-	{"vfound", (void *) &xSoc.vict_found, olced_str, NULL},
-	{"cself", (void *) &xSoc.char_auto, olced_str, NULL},
-	{"oself", (void *) &xSoc.others_auto, olced_str, NULL},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"show", NULL, olced_olded, (const void *) sedit_show, NULL},
+	{"name", NULL, olced_olded, (const void *) sedit_name, NULL},
+	{"create", NULL, olced_olded, (const void *) sedit_create, NULL},
+	{"delete", NULL, olced_olded, (const void *) sedit_delete, NULL},
+	{"cnoarg", (void *) &xSoc.char_no_arg, olced_str, NULL, NULL},
+	{"onoarg", (void *) &xSoc.others_no_arg, olced_str, NULL, NULL},
+	{"cfound", (void *) &xSoc.char_found, olced_str, NULL, NULL},
+	{"ofound", (void *) &xSoc.others_found, olced_str, NULL, NULL},
+	{"vfound", (void *) &xSoc.vict_found, olced_str, NULL, NULL},
+	{"cself", (void *) &xSoc.char_auto, olced_str, NULL, NULL},
+	{"oself", (void *) &xSoc.others_auto, olced_str, NULL, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type cmd_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) cmdedit_show},
-	{"create", NULL, olced_olded, (const void *) cmdedit_create},
-	{"name", NULL, olced_olded, (const void *) cmdedit_name},
-	{"rearrange", NULL, olced_olded, (void *) cmdedit_rearrange},
+	{"show", NULL, olced_olded, (const void *) cmdedit_show, NULL},
+	{"create", NULL, olced_olded, (const void *) cmdedit_create, NULL},
+	{"name", NULL, olced_olded, (const void *) cmdedit_name, NULL},
+	{"rearrange", NULL, olced_olded, (void *) cmdedit_rearrange, NULL},
 
-	{"level", (void *) &xCmd.level, olced_number,
-	 (const void *) validate_level},
+	{"level", (void *) &xCmd.level, olced_number, NULL,
+	 validate_level},
 	{"position", (void *) &xCmd.position, olced_flag,
-	 (const void *) position_flags},
-	{"log", (void *) &xCmd.log, olced_flag, (const void *) log_flags},
-	{"fShow", (void *) &xCmd.show, olced_bool, NULL},
-	{"dofun", NULL, olced_olded, (const void *) cmdedit_dofun},
-	{"delete", NULL, olced_olded, (const void *) cmdedit_delete},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	 (const void *) position_flags, NULL},
+	{"log", (void *) &xCmd.log, olced_flag, (const void *) log_flags, NULL},
+	{"fShow", (void *) &xCmd.show, olced_bool, NULL, NULL},
+	{"dofun", NULL, olced_olded, (const void *) cmdedit_dofun, NULL},
+	{"delete", NULL, olced_olded, (const void *) cmdedit_delete, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type skill_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) skedit_show},
-	{"create", NULL, olced_olded, (const void *) skedit_create},
-	{"name", (void *) &xSkill.name, olced_str, NULL},
-	{"levels", NULL, olced_olded, (const void *) skedit_levels},
-	{"ratings", NULL, olced_olded, (const void *) skedit_ratings},
-	{"spellfun", NULL, olced_olded, (const void *) skedit_spellfun},
+	{"show", NULL, olced_olded, (const void *) skedit_show, NULL},
+	{"create", NULL, olced_olded, (const void *) skedit_create, NULL},
+	{"name", (void *) &xSkill.name, olced_str, NULL, NULL},
+	{"levels", NULL, olced_olded, (const void *) skedit_levels, NULL},
+	{"ratings", NULL, olced_olded, (const void *) skedit_ratings, NULL},
+	{"spellfun", NULL, olced_olded, (const void *) skedit_spellfun, NULL},
 
 	{"target", (void *) &xSkill.target, olced_flag,
-	 (const void *) target_flags},
+	 (const void *) target_flags, NULL},
 	{"minpos", (void *) &xSkill.minimum_position, olced_flag,
-	 (const void *) position_flags},
-	{"gsn", NULL, olced_olded, (const void *) skedit_gsn},
-	{"minmana", (void *) &xSkill.min_mana, olced_number, NULL},
-	{"beats", (void *) &xSkill.beats, olced_number, NULL},
-	{"damnoun", (void *) &xSkill.noun_damage, olced_str, NULL},
-	{"msgoff", (void *) &xSkill.msg_off, olced_str, NULL},
-	{"msgobj", (void *) &xSkill.msg_obj, olced_str, NULL},
-	{"delete", NULL, olced_olded, (const void *) skedit_delete},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	 (const void *) position_flags, NULL},
+	{"gsn", NULL, olced_olded, (const void *) skedit_gsn, NULL},
+	{"minmana", (void *) &xSkill.min_mana, olced_number, NULL, NULL},
+	{"beats", (void *) &xSkill.beats, olced_number, NULL, NULL},
+	{"damnoun", (void *) &xSkill.noun_damage, olced_str, NULL, NULL},
+	{"msgoff", (void *) &xSkill.msg_off, olced_str, NULL, NULL},
+	{"msgobj", (void *) &xSkill.msg_obj, olced_str, NULL, NULL},
+	{"delete", NULL, olced_olded, (const void *) skedit_delete, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type group_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (const void *) gredit_show},
-	{"create", NULL, olced_olded, (const void *) gredit_create},
+	{"show", NULL, olced_olded, (const void *) gredit_show, NULL},
+	{"create", NULL, olced_olded, (const void *) gredit_create, NULL},
 
-	{"name", (void *) &xGroup.name, olced_str,
-	 (const void *) validate_groupname},
-	{"ratings", NULL, olced_olded, (const void *) gredit_ratings},
-	{"spells", NULL, olced_olded, (const void *) gredit_spells},
-	{"delete", NULL, olced_olded, (const void *) gredit_delete},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"name", (void *) &xGroup.name, olced_str, NULL,
+	 validate_groupname},
+	{"ratings", NULL, olced_olded, (const void *) gredit_ratings, NULL},
+	{"spells", NULL, olced_olded, (const void *) gredit_spells, NULL},
+	{"delete", NULL, olced_olded, (const void *) gredit_delete, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type race_olc_comm_table[] = {
-	{"create", NULL, olced_olded, (const void *) raedit_create},
-	{"delete", NULL, olced_olded, (const void *) raedit_delete},
-	{"show", NULL, olced_olded, (const void *) raedit_show},
-	{"name", NULL, olced_olded, (const void *) raedit_name},
-	{"act", (void *) &xRace.act, olced_flag, (const void *) act_flags},
-	{"aff", (void *) &xRace.aff, olced_flag, (const void *) affect_flags},
-	{"form", (void *) &xRace.form, olced_flag, (const void *) form_flags},
-	{"off", (void *) &xRace.off, olced_flag, (const void *) off_flags},
-	{"imm", (void *) &xRace.imm, olced_flag, (const void *) imm_flags},
-	{"res", (void *) &xRace.res, olced_flag, (const void *) res_flags},
-	{"vuln", (void *) &xRace.vuln, olced_flag, (const void *) vuln_flags},
-	{"parts", (void *) &xRace.parts, olced_flag, (const void *) part_flags},
-	{"pcrace", (void *) &xRace.pc_race, olced_bool, NULL},
-	{"points", (void *) &xRace.points, olced_number, NULL},
-	{"list", NULL, olced_olded, (const void *) raedit_list},
-	{"stats", NULL, olced_olded, (const void *) raedit_stats},
-	{"mstats", NULL, olced_olded, (const void *) raedit_mstats},
-	{"skills", NULL, olced_olded, (const void *) raedit_skills},
-	{"size", (void *) &xRace.size, olced_flag, (const void *) size_flags},
-	{"classx", NULL, olced_olded, (const void *) raedit_classx},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"create", NULL, olced_olded, (const void *) raedit_create, NULL},
+	{"delete", NULL, olced_olded, (const void *) raedit_delete, NULL},
+	{"show", NULL, olced_olded, (const void *) raedit_show, NULL},
+	{"name", NULL, olced_olded, (const void *) raedit_name, NULL},
+	{"act", (void *) &xRace.act, olced_flag, (const void *) act_flags, NULL},
+	{"aff", (void *) &xRace.aff, olced_flag, (const void *) affect_flags, NULL},
+	{"form", (void *) &xRace.form, olced_flag, (const void *) form_flags, NULL},
+	{"off", (void *) &xRace.off, olced_flag, (const void *) off_flags, NULL},
+	{"imm", (void *) &xRace.imm, olced_flag, (const void *) imm_flags, NULL},
+	{"res", (void *) &xRace.res, olced_flag, (const void *) res_flags, NULL},
+	{"vuln", (void *) &xRace.vuln, olced_flag, (const void *) vuln_flags, NULL},
+	{"parts", (void *) &xRace.parts, olced_flag, (const void *) part_flags, NULL},
+	{"pcrace", (void *) &xRace.pc_race, olced_bool, NULL, NULL},
+	{"points", (void *) &xRace.points, olced_number, NULL, NULL},
+	{"list", NULL, olced_olded, (const void *) raedit_list, NULL},
+	{"stats", NULL, olced_olded, (const void *) raedit_stats, NULL},
+	{"mstats", NULL, olced_olded, (const void *) raedit_mstats, NULL},
+	{"skills", NULL, olced_olded, (const void *) raedit_skills, NULL},
+	{"size", (void *) &xRace.size, olced_flag, (const void *) size_flags, NULL},
+	{"classx", NULL, olced_olded, (const void *) raedit_classx, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type class_olc_comm_table[] = {
-	{"create", NULL, olced_olded, (const void *) cledit_create},
-	{"delete", NULL, olced_olded, (const void *) cledit_delete},
-	{"show", NULL, olced_olded, (const void *) cledit_show},
-
-	{"name", (void *) &xClass.name, olced_str,
-	 (const void *) validate_classname},
-	{"prime", NULL, olced_olded, (const void *) cledit_prime},
-
-	{"weapon", (void *) &xClass.weapon, olced_vnum,
-	 (const void *) validate_weapon},
-	{"adept", (void *) &xClass.skill_adept, olced_number,
-	 (const void *) validate_adept},
-	{"thac0", (void *) &xClass.thac0_00, olced_number, NULL},
-	{"thac32", (void *) &xClass.thac0_32, olced_number, NULL},
-
-	{"hpmin", (void *) &xClass.hp_min, olced_number,
-	 (const void *) validate_hmv},
-	{"hpmax", (void *) &xClass.hp_max, olced_number,
-	 (const void *) validate_hmv},
-	{"fmana", (void *) &xClass.fMana, olced_bool, NULL},
-	{"guilds", NULL, olced_olded, (const void *) cledit_guilds},
-
-	{"basegroup", (void *) &xClass.base_group, olced_str,
-	 (const void *) validate_group},
-	{"default", (void *) &xClass.default_group, olced_str,
-	 (const void *) validate_group},
-	{"skill", NULL, olced_olded, (const void *) cledit_skill},
-	{"commands", NULL, olced_olded, (const void *) show_commands},
-	{"?", NULL, olced_olded, (const void *) show_help},
-	{"version", NULL, olced_olded, (const void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"create", NULL, olced_olded, (const void *) cledit_create, NULL},
+	{"delete", NULL, olced_olded, (const void *) cledit_delete, NULL},
+	{"show", NULL, olced_olded, (const void *) cledit_show, NULL},
+
+	{"name", (void *) &xClass.name, olced_str, NULL,
+	 validate_classname},
+	{"prime", NULL, olced_olded, (const void *) cledit_prime, NULL},
+
+	{"weapon", (void *) &xClass.weapon, olced_vnum, NULL,
+	 validate_weapon},
+	{"adept", (void *) &xClass.skill_adept, olced_number, NULL,
+	 validate_adept},
+	{"thac0", (void *) &xClass.thac0_00, olced_number, NULL, NULL},
+	{"thac32", (void *) &xClass.thac0_32, olced_number, NULL, NULL},
+
+	{"hpmin", (void *) &xClass.hp_min, olced_number, NULL,
+	 validate_hmv},
+	{"hpmax", (void *) &xClass.hp_max, olced_number, NULL,
+	 validate_hmv},
+	{"fmana", (void *) &xClass.fMana, olced_bool, NULL, NULL},
+	{"guilds", NULL, olced_olded, (const void *) cledit_guilds, NULL},
+
+	{"basegroup", (void *) &xClass.base_group, olced_str, NULL,
+	 validate_group},
+	{"default", (void *) &xClass.default_group, olced_str, NULL,
+	 validate_group},
+	{"skill", NULL, olced_olded, (const void *) cledit_skill, NULL},
+	{"commands", NULL, olced_olded, (const void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (const void *) show_help, NULL},
+	{"version", NULL, olced_olded, (const void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
 const struct olc_comm_type deity_olc_comm_table[] = {
-	{"show", NULL, olced_olded, (void *) dedit_show},
-	{"create", NULL, olced_olded, (void *) dedit_create},
-	{"delete", NULL, olced_olded, (void *) dedit_delete},
-	{"list", NULL, olced_olded, (void *) dedit_list},
-	{"name", (void *) &xDeity.name, olced_str, NULL},
-	{"desc", (void *) &xDeity.desc, olced_str, NULL},
-	{"skill", (void *) &xDeity.skillname, olced_str, NULL},
-	{"commands", NULL, olced_olded, (void *) show_commands},
-	{"?", NULL, olced_olded, (void *) show_help},
-	{"version", NULL, olced_olded, (void *) show_version},
-	{NULL, NULL, NULL, NULL}
+	{"show", NULL, olced_olded, (void *) dedit_show, NULL},
+	{"create", NULL, olced_olded, (void *) dedit_create, NULL},
+	{"delete", NULL, olced_olded, (void *) dedit_delete, NULL},
+	{"list", NULL, olced_olded, (void *) dedit_list, NULL},
+	{"name", (void *) &xDeity.name, olced_str, NULL, NULL},
+	{"desc", (void *) &xDeity.desc, olced_str, NULL, NULL},
+	{"skill", (void *) &xDeity.skillname, olced_str, NULL, NULL},
+	{"commands", NULL, olced_olded, (void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (void *) show_help, NULL},
+	{"version", NULL, olced_olded, (void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
+};
+
+const struct olc_comm_type chan_olc_comm_table[] = {
+	{"show", NULL, olced_olded, (void *) chanedit_show, NULL},
+	{"create", NULL, olced_olded, (void *) chanedit_create, NULL},
+	{"gcn", NULL, olced_olded, (void *) chanedit_gcn, NULL},
+	{"type", (void *) &xChan.spec_flag, olced_flag, (void *) chan_types, NULL},
+	{"bit", (void *) &xChan.bit, olced_flag, (void *) comm_flags, NULL},
+	{"format", (void *) &xChan.format, olced_str, NULL, NULL},
+	{"name", (void *) &xChan.name, olced_str, NULL, NULL},
+	{"description", (void *) &xChan.description, olced_str, NULL, NULL},
+	{"colour", NULL, olced_olded, (void *) chanedit_colour, NULL},
+	{"length", (void *) &xChan.page_length, olced_number, NULL, NULL},
+	{"delete", NULL, olced_olded, (void *) chanedit_delete, NULL},
+	{"list", NULL, olced_olded, (void *) chanedit_list, NULL},
+	{"commands", NULL, olced_olded, (void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (void *) show_help, NULL},
+	{"version", NULL, olced_olded, (void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
+};
+
+const struct olc_comm_type mud_olc_comm_table[] = {
+	{"show", NULL, olced_olded, (void *) mudedit_show, NULL},
+	{"flags", (void *) &xMud.mud_flags, olced_flag, (void *) mud_flags, NULL},
+	{"pulsepersec", (void *) &xMud.pulsepersec, olced_number, NULL, NULL},
+	{"rand_factor", (void *) &xMud.rand_factor, olced_number, NULL, NULL},
+	{"weath_unit", (void *) &xMud.weath_unit, olced_number, NULL, NULL},
+	{"max_vector", (void *) &xMud.max_vector, olced_number, NULL, NULL},
+	{"climate_factor", (void *) &xMud.climate_factor, olced_number, NULL, NULL},
+	{"commands", NULL, olced_olded, (void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (void *) show_help, NULL},
+	{"version", NULL, olced_olded, (void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
 };
 
+const struct olc_comm_type song_olc_comm_table[] = {
+	{"show", NULL, olced_olded, (void *) songedit_show, NULL},
+	{"group", (void *) &xSong.group, olced_str, NULL, NULL},
+	{"name", (void *) &xSong.name, olced_str, NULL, NULL},
+	{"lyrics", NULL, olced_olded, (void *) songedit_lyrics, NULL},
+	{"delete", NULL, olced_olded, (void *) songedit_delete, NULL},
+	{"create", NULL, olced_olded, (void *) songedit_create, NULL},
+	{"commands", NULL, olced_olded, (void *) show_commands, NULL},
+	{"?", NULL, olced_olded, (void *) show_help, NULL},
+	{"version", NULL, olced_olded, (void *) show_version, NULL},
+	{NULL, NULL, NULL, NULL, NULL}
+};
 /*****************************************************************************
  *                          End Interpreter Tables.                          *
  *****************************************************************************/
@@ -859,7 +849,7 @@
  ****************************************************************************/
 bool edit_done(CHAR_DATA * ch)
 {
-	if (ch->desc->editor > 0)
+	if (ch->desc->editor != ED_NONE)
 	{
 		act("$n stop using the $t editor.", ch, olc_ed_name_long(ch), NULL,
 			TO_ROOM);
@@ -868,7 +858,7 @@
 	}
 
 	ch->desc->pEdit = NULL;
-	ch->desc->editor = 0;
+	ch->desc->editor = ED_NONE;
 	return FALSE;
 }
 
@@ -896,6 +886,9 @@
 	RACE_DATA *pRace;
 	CLASS_DATA *pClass;
 	DEITY_DATA *pDeity;
+	CHANNEL_DATA *pChan;
+	MUD *nMud;
+	SONG_DATA *pSong;
 	int temp;
 	void *puntero;
 	const char *logline = argument;
@@ -907,7 +900,8 @@
 		if (LOWER(arg[0]) == LOWER(table[temp].name[0])
 			&& !str_prefix(arg, table[temp].name))
 		{
-			if ((!IS_NPC(ch) && IS_SET(ch->act, PLR_LOG)) || fLogAll)
+			if ((!IS_NPC(ch) && IS_SET(ch->act, PLR_LOG))
+				|| IS_SET(mud_info.mud_flags, MUD_LOGALL))
 			{
 				sprintf(log_buf, "Log %s: %s", ch->name, logline);
 				log_string(log_buf);
@@ -915,9 +909,8 @@
 
 			if (ch->desc != NULL && ch->desc->snoop_by != NULL)
 			{
-				write_to_buffer(ch->desc->snoop_by, "% ", 2);
-				write_to_buffer(ch->desc->snoop_by, logline, 0);
-				write_to_buffer(ch->desc->snoop_by, "\n\r", 2);
+				d_print(ch->desc->snoop_by, "% ", 2);
+				d_println(ch->desc->snoop_by, logline, 0);
 			}
 
 			switch (ch->desc->editor)
@@ -933,7 +926,7 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter) && tArea)
+					 table[temp].parameter, table[temp].validate) && tArea)
 					SET_BIT(tArea->area_flags, AREA_CHANGED);
 				return TRUE;
 				break;
@@ -948,7 +941,8 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter) && tArea != NULL)
+					 table[temp].parameter, table[temp].validate)
+					&& tArea != NULL)
 					SET_BIT(tArea->area_flags, AREA_CHANGED);
 				return TRUE;
 				break;
@@ -963,7 +957,8 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter) && tArea != NULL)
+					 table[temp].parameter, table[temp].validate)
+					&& tArea != NULL)
 					SET_BIT(tArea->area_flags, AREA_CHANGED);
 				return TRUE;
 				break;
@@ -977,13 +972,13 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
+					 table[temp].parameter, table[temp].validate))
 					SET_BIT(pArea->area_flags, AREA_CHANGED);
 				return TRUE;
 				break;
 			case ED_MPCODE:
 				EDIT_MPCODE(ch, pMProg);
-				tArea = get_vnum_area(pMProg->vnum);
+				tArea = pMProg->area;
 				if (table[temp].argument)
 					puntero =
 						(void *) ((int) table[temp].argument -
@@ -992,13 +987,13 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
+					 table[temp].parameter, table[temp].validate))
 					SET_BIT(tArea->area_flags, AREA_CHANGED);
 				return TRUE;
 				break;
 			case ED_OPCODE:
 				EDIT_OPCODE(ch, pOProg);
-				tArea = get_vnum_area(pOProg->vnum);
+				tArea = pOProg->area;
 				if (table[temp].argument)
 					puntero =
 						(void *) ((int) table[temp].argument -
@@ -1007,13 +1002,13 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
+					 table[temp].parameter, table[temp].validate))
 					SET_BIT(tArea->area_flags, AREA_CHANGED);
 				return TRUE;
 				break;
 			case ED_RPCODE:
 				EDIT_RPCODE(ch, pRProg);
-				tArea = get_vnum_area(pRProg->vnum);
+				tArea = pRProg->area;
 				if (table[temp].argument)
 					puntero =
 						(void *) ((int) table[temp].argument -
@@ -1022,7 +1017,7 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
+					 table[temp].parameter, table[temp].validate))
 					SET_BIT(tArea->area_flags, AREA_CHANGED);
 				return TRUE;
 				break;
@@ -1036,7 +1031,7 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
+					 table[temp].parameter, table[temp].validate))
 					save_helps();
 				return TRUE;
 				break;
@@ -1050,8 +1045,8 @@
 					puntero = NULL;
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
-					save_social_table();
+					 table[temp].parameter, table[temp].validate))
+					rw_socials(action_write);
 				return TRUE;
 				break;
 			case ED_CLAN:
@@ -1065,8 +1060,8 @@
 
 				if ((*table[temp].function)
 					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
-					save_clans();
+					 table[temp].parameter, table[temp].validate))
+					rw_clans(action_write);
 				return TRUE;
 				break;
 			case ED_DEITY:
@@ -1076,387 +1071,133 @@
 						(void *) ((int) table[temp].argument - (int) &xDeity +
 								  (int) pDeity);
 				else
-					puntero = NULL;
-				if ((*table[temp].function)
-					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
-					save_deities();
-				return TRUE;
-				break;
-			case ED_CMD:
-				EDIT_CMD(ch, pCmd);
-				if (table[temp].argument)
-					puntero =
-						(void *) ((int) table[temp].argument -
-								  (int) &xCmd + (int) pCmd);
-				else
-					puntero = NULL;
-
-				if ((*table[temp].function)
-					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
-					save_commands();
-				return TRUE;
-				break;
-			case ED_SKILL:
-				EDIT_SKILL(ch, pSkill);
-				if (table[temp].argument)
-					puntero =
-						(void *) ((int) table[temp].argument - (int) &xSkill +
-								  (int) pSkill);
-				else
-					puntero = NULL;
-				if ((*table[temp].function)
-					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
-					save_skills();
-				return TRUE;
-				break;
-			case ED_GROUP:
-				EDIT_GROUP(ch, pGroup);
-				if (table[temp].argument)
-					puntero =
-						(void *) ((int) table[temp].argument - (int) &xGroup +
-								  (int) pGroup);
-				else
-					puntero = NULL;
-				if ((*table[temp].function)
-					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
-					save_groups();
-				return TRUE;
-				break;
-			case ED_RACE:
-				EDIT_RACE(ch, pRace);
-				if (table[temp].argument)
-					puntero =
-						(void *) ((int) table[temp].argument - (int) &xRace +
-								  (int) pRace);
-				else
-					puntero = NULL;
-				if ((*table[temp].function)
-					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
-					save_races();
-				return TRUE;
-				break;
-			case ED_CLASS:
-				EDIT_CLASS(ch, pClass);
-				if (table[temp].argument)
-					puntero =
-						(void *) ((int) table[temp].argument - (int) &xClass +
-								  (int) pClass);
-				else
-					puntero = NULL;
-				if ((*table[temp].function)
-					(table[temp].name, ch, argument, puntero,
-					 table[temp].parameter))
-					save_classes();
-				return TRUE;
-				break;
-			}
-		}
-	}
-
-	return FALSE;
-}
-
-/* Area Interpreter, called by do_aedit. */
-void aedit(CHAR_DATA * ch, char *argument)
-{
-	AREA_DATA *pArea;
-
-	EDIT_AREA(ch, pArea);
-
-	if (!IS_BUILDER(ch, pArea))
-	{
-		chprintln(ch, "AEdit:  Insufficient security to modify area.");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		aedit_show(ch, argument);
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, area_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-/* Room Interpreter, called by do_redit. */
-void redit(CHAR_DATA * ch, char *argument)
-{
-	AREA_DATA *pArea;
-	ROOM_INDEX_DATA *pRoom;
-
-	EDIT_ROOM(ch, pRoom);
-	pArea = pRoom->area;
-
-	if (!IS_BUILDER(ch, pArea))
-	{
-		chprintln(ch, "REdit:  Insufficient security to modify room.");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		redit_show(ch, argument);
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, room_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-/* Object Interpreter, called by do_oedit. */
-void oedit(CHAR_DATA * ch, char *argument)
-{
-	AREA_DATA *pArea;
-	OBJ_INDEX_DATA *pObj;
-
-	EDIT_OBJ(ch, pObj);
-	pArea = pObj->area;
-
-	if (!IS_BUILDER(ch, pArea))
-	{
-		chprintln(ch, "OEdit: Insufficient security to modify area.");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		oedit_show(ch, argument);
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, obj_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-/* Mobile Interpreter, called by do_medit. */
-void medit(CHAR_DATA * ch, char *argument)
-{
-	AREA_DATA *pArea;
-	MOB_INDEX_DATA *pMob;
-
-	EDIT_MOB(ch, pMob);
-	pArea = pMob->area;
-
-	if (!IS_BUILDER(ch, pArea))
-	{
-		chprintln(ch, "mEdit: Insufficient security to modify area.");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		medit_show(ch, argument);
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, mob_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-void cedit(CHAR_DATA * ch, char *argument)
-{
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		cedit_show(ch, argument);
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, clan_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-void cmdedit(CHAR_DATA * ch, char *argument)
-{
-	if (get_trust(ch) < MAX_LEVEL - 5)
-	{
-		chprintln(ch, "Insuffecient security to modify command data");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		cmdedit_show(ch, argument);
-		return;
-	}
-	if (!process_olc_command(ch, argument, cmd_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-void skedit(CHAR_DATA * ch, char *argument)
-{
-	if (get_trust(ch) < MAX_LEVEL - 5)
-	{
-		chprintln(ch, "Insuffecient security to modify race data");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		skedit_show(ch, argument);
-		return;
-	}
-	if (!process_olc_command(ch, argument, skill_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-void gredit(CHAR_DATA * ch, char *argument)
-{
-	if (get_trust(ch) < MAX_LEVEL - 5)
-	{
-		chprintln(ch, "Insuffecient security to modify group data");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		gredit_show(ch, argument);
-		return;
-	}
-	if (!process_olc_command(ch, argument, group_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-void raedit(CHAR_DATA * ch, char *argument)
-{
-	if (get_trust(ch) < MAX_LEVEL - 5)
-	{
-		chprintln(ch, "Insuffecient security to modify race data");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		raedit_show(ch, argument);
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, race_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
-void cledit(CHAR_DATA * ch, char *argument)
-{
-	if (get_trust(ch) < MAX_LEVEL - 5)
-	{
-		chprintln(ch, "Insuffecient security to modify class data");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
+					puntero = NULL;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_deities(action_write);
+				return TRUE;
+				break;
+			case ED_CMD:
+				EDIT_CMD(ch, pCmd);
+				if (table[temp].argument)
+					puntero =
+						(void *) ((int) table[temp].argument -
+								  (int) &xCmd + (int) pCmd);
+				else
+					puntero = NULL;
 
-	if (emptystring(argument))
-	{
-		cledit_show(ch, argument);
-		return;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_commands(action_write);
+				return TRUE;
+				break;
+			case ED_SKILL:
+				EDIT_SKILL(ch, pSkill);
+				if (table[temp].argument)
+					puntero =
+						(void *) ((int) table[temp].argument - (int) &xSkill +
+								  (int) pSkill);
+				else
+					puntero = NULL;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_skills(action_write);
+				return TRUE;
+				break;
+			case ED_GROUP:
+				EDIT_GROUP(ch, pGroup);
+				if (table[temp].argument)
+					puntero =
+						(void *) ((int) table[temp].argument - (int) &xGroup +
+								  (int) pGroup);
+				else
+					puntero = NULL;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_groups(action_write);
+				return TRUE;
+				break;
+			case ED_RACE:
+				EDIT_RACE(ch, pRace);
+				if (table[temp].argument)
+					puntero =
+						(void *) ((int) table[temp].argument - (int) &xRace +
+								  (int) pRace);
+				else
+					puntero = NULL;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_races(action_write);
+				return TRUE;
+				break;
+			case ED_CLASS:
+				EDIT_CLASS(ch, pClass);
+				if (table[temp].argument)
+					puntero =
+						(void *) ((int) table[temp].argument - (int) &xClass +
+								  (int) pClass);
+				else
+					puntero = NULL;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_classes(action_write);
+				return TRUE;
+				break;
+			case ED_CHAN:
+				EDIT_CHAN(ch, pChan);
+				if (table[temp].argument)
+					puntero =
+						(void *) ((int) table[temp].argument - (int) &xChan +
+								  (int) pChan);
+				else
+					puntero = NULL;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_channels(action_write);
+				return TRUE;
+				break;
+			case ED_MUD:
+				EDIT_MUD(ch, nMud);
+				if (table[temp].argument)
+					puntero =
+						(void *) ((int) table[temp].argument - (int) &xMud +
+								  (int) nMud);
+				else
+					puntero = NULL;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_mud_data(action_write);
+				return TRUE;
+				break;
+			case ED_SONG:
+				EDIT_SONG(ch, pSong);
+				if (table[temp].argument)
+					puntero =
+						(void *) ((int) table[temp].argument - (int) &xSong +
+								  (int) pSong);
+				else
+					puntero = NULL;
+				if ((*table[temp].function)
+					(table[temp].name, ch, argument, puntero,
+					 table[temp].parameter, table[temp].validate))
+					rw_music(action_write);
+				return TRUE;
+				break;
+			}
+		}
 	}
 
-	if (!process_olc_command(ch, argument, class_olc_comm_table))
-		interpret(ch, argument);
-	return;
+	return FALSE;
 }
 
-const struct editor_cmd_type editor_table[] = {
-/*  {   command		function	}, */
-
-	{"area", do_aedit},
-	{"room", do_redit},
-	{"object", do_oedit},
-	{"mobile", do_medit},
-	{"mpcode", do_mpedit},
-	{"hedit", do_hedit},
-	{"social", do_sedit},
-	{"clan", do_cedit},
-	{"command", do_cmdedit},
-	{"skill", do_skedit},
-	{"group", do_gredit},
-	{"race", do_raedit},
-	{"class", do_cledit},
-	{"deity", do_dedit},
-	{NULL, 0}
-};
-
 /* Entry point for all editors. */
 CH_CMD(do_olc)
 {
@@ -1468,18 +1209,18 @@
 
 	argument = one_argument(argument, command);
 
-	if (command[0] == '\0')
+	if (IS_NULLSTR(command))
 	{
 		do_oldhelp(ch, "olc");
 		return;
 	}
 
 	/* Search Table and Dispatch Command. */
-	for (cmd = 0; editor_table[cmd].name != NULL; cmd++)
+	for (cmd = 0; cmd < ED_MAX; cmd++)
 	{
-		if (!str_prefix(command, editor_table[cmd].name))
+		if (!str_prefix(command, olc_ed_table[cmd].name))
 		{
-			(*editor_table[cmd].do_fun) (ch, argument);
+			(*olc_ed_table[cmd].do_fun) (ch, argument);
 			return;
 		}
 	}
@@ -1489,6 +1230,22 @@
 	return;
 }
 
+CHANNEL_DATA *get_chan_data(int chan)
+{
+	if (chan >= 0 && chan < maxChannel)
+		return &channel_table[chan];
+	else
+		return NULL;
+}
+
+SONG_DATA *get_song_data(int song)
+{
+	if (song >= 0 && song < maxSongs)
+		return &song_table[song];
+	else
+		return NULL;
+}
+
 SKILL_DATA *get_skill_data(int skill)
 {
 	if (skill > -1 && skill < maxSkill)
@@ -1609,6 +1366,8 @@
 	}
 	else if (!str_cmp(arg, "delete"))
 	{
+		char filename[512];
+
 		if (ch->pcdata->security < 9)
 		{
 			chprintln(ch, "AEdit : Seguridad insuficiente para delete area.");
@@ -1628,7 +1387,8 @@
 		}
 
 		clean_area_links(pArea);
-		unlink(pArea->file_name);
+		sprintf(filename, "%s%s", AREA_DIR, pArea->file_name);
+		unlink(filename);
 		unlink_area(pArea);
 		free_area(pArea);
 		do_asave(NULL, "changed");
@@ -1673,7 +1433,7 @@
 	}
 	else if (!str_cmp(arg1, "create"))	/* redit create <vnum> */
 	{
-		if (argument[0] == '\0' || atol(argument) == 0)
+		if (IS_NULLSTR(argument) || atol(argument) == 0)
 		{
 			chprintln(ch, "Syntax:  edit room create [vnum]");
 			return;
@@ -1762,7 +1522,7 @@
 		if (!str_cmp(arg1, "create"))
 		{
 			value = atol(argument);
-			if (argument[0] == '\0' || value == 0)
+			if (IS_NULLSTR(argument) || value == 0)
 			{
 				chprintln(ch, "Syntax:  edit object create [vnum]");
 				return;
@@ -1838,7 +1598,7 @@
 		if (!str_cmp(arg1, "create"))
 		{
 			value = atol(argument);
-			if (arg1[0] == '\0' || value == 0)
+			if (IS_NULLSTR(arg1) || value == 0)
 			{
 				chprintln(ch, "Syntax:  edit mobile create [vnum]");
 				return;
@@ -1898,7 +1658,7 @@
 
 	if (!str_cmp(arg, "save"))
 	{
-		save_clans();
+		rw_clans(action_write);
 		chprintln(ch, "Clan database saved.");
 		return;
 	}
@@ -1942,7 +1702,7 @@
 
 	if (!str_cmp(arg, "save"))
 	{
-		save_commands();
+		rw_commands(action_write);
 		chprintln(ch, "Command database saved.");
 		return;
 	}
@@ -2008,7 +1768,7 @@
 	}
 	else if (!str_cmp(arg, "save"))
 	{
-		save_skills();
+		rw_skills(action_write);
 		chprintln(ch, "Skill database saved.");
 		return;
 	}
@@ -2067,7 +1827,7 @@
 	}
 	else if (!str_cmp(arg, "save"))
 	{
-		save_groups();
+		rw_groups(action_write);
 		chprintln(ch, "Group database saved.");
 		return;
 	}
@@ -2108,7 +1868,7 @@
 	}
 	else if (!str_cmp(arg, "save"))
 	{
-		save_races();
+		rw_races(action_write);
 		chprintln(ch, "Race database saved.");
 		return;
 	}
@@ -2172,7 +1932,7 @@
 	}
 	else if (!str_cmp(arg, "save"))
 	{
-		save_classes();
+		rw_classes(action_write);
 		chprintln(ch, "Class database saved.");
 		return;
 	}
@@ -2193,6 +1953,154 @@
 	return;
 }
 
+int channel_lookup(const char *arg)
+{
+	int i;
+
+	for (i = 0; i < maxChannel; i++)
+	{
+		if (!str_prefix(arg, channel_table[i].name))
+			return i;
+	}
+	return -1;
+}
+
+CH_CMD(do_chanedit)
+{
+	CHANNEL_DATA *pChan;
+	int value;
+	char arg[MSL];
+
+	if (IS_NPC(ch))
+		return;
+
+	pChan = &channel_table[0];
+
+	argument = one_argument(argument, arg);
+
+	if (IS_NULLSTR(arg))
+	{
+		chprintln(ch, "Syntax: chanedit create\n\r" "      : chanedit save\n\r"
+				  "      : chanedit <#|name>");
+		return;
+	}
+
+	if (is_number(arg))
+		value = atoi(arg);
+	else
+		value = channel_lookup(arg);
+
+	if (value > -1)
+	{
+		pChan = get_chan_data(value);
+
+		if (!pChan)
+		{
+			chprintln(ch, "That channel does not exist.");
+			return;
+		}
+
+	}
+	else if (!str_cmp(arg, "save"))
+	{
+		rw_channels(action_write);
+		chprintln(ch, "Channel database saved.");
+		return;
+	}
+	else if (!str_cmp(arg, "make") || !str_cmp(arg, "create"))
+	{
+		if (ch->pcdata->security < 9)
+		{
+			chprintln
+				(ch,
+				 "chanEdit : Insuffecient security to create new channels.");
+			return;
+		}
+
+		chanedit_create(ch, argument);
+
+		return;
+	}
+
+	edit_start(ch, pChan, ED_CHAN);
+	return;
+}
+
+CH_CMD(do_songedit)
+{
+	SONG_DATA *pSong;
+	int value;
+	char arg[MSL];
+
+	if (IS_NPC(ch))
+		return;
+
+	pSong = &song_table[0];
+
+	argument = one_argument(argument, arg);
+
+	if (IS_NULLSTR(arg))
+	{
+		chprintln(ch, "Syntax: songedit create\n\r" "      : songedit save\n\r"
+				  "      : songedit <#|name>");
+		return;
+	}
+
+	if (is_number(arg))
+		value = atoi(arg);
+	else
+		value = song_lookup(arg);
+
+	if (value > -1)
+	{
+		pSong = get_song_data(value);
+
+		if (!pSong)
+		{
+			chprintln(ch, "That song does not exist.");
+			return;
+		}
+
+	}
+	else if (!str_cmp(arg, "save"))
+	{
+		rw_music(action_write);
+		chprintln(ch, "Song database saved.");
+		return;
+	}
+	else if (!str_cmp(arg, "make") || !str_cmp(arg, "create"))
+	{
+		if (ch->pcdata->security < 9)
+		{
+			chprintln
+				(ch, "SongEdit : Insuffecient security to create new songs.");
+			return;
+		}
+
+		songedit_create(ch, argument);
+
+		return;
+	}
+
+	edit_start(ch, pSong, ED_SONG);
+	return;
+}
+
+CH_CMD(do_mudedit)
+{
+	if (IS_NPC(ch))
+		return;
+
+	if (get_trust(ch) < MAX_LEVEL - 1)
+	{
+		chprintln(ch, "Insufficient security to edit mud data.");
+		return;
+	}
+
+	edit_start(ch, &mud_info, ED_MUD);
+	return;
+}
+
 void display_resets(CHAR_DATA * ch)
 {
 	ROOM_INDEX_DATA *pRoom;
@@ -2381,8 +2289,12 @@
 				continue;
 			}
 
-			sprintf(buf, "R[%5ld] Exits are randomized in %s\n\r",
-					pReset->arg1, pRoomIndex->name);
+			sprintf(buf, "R[%5ld] Set to randomize %s %s.\n\r",
+					pReset->arg1,
+					pReset->arg3 == 0 ? "exits" : pReset->arg2 ==
+					0 ? "any available exit" : dir_name[pReset->arg2 - 1],
+					pReset->arg3 == 0 ? "in room" : pReset->arg3 ==
+					1 ? "to this area" : "to the world");
 			strcat(final, buf);
 
 			break;
@@ -2451,7 +2363,7 @@
 	 * Display resets in current room.
 	 * -------------------------------
 	 */
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		if (ch->in_room->reset_first)
 		{
@@ -2603,20 +2515,47 @@
 			SET_BIT(ch->in_room->area->area_flags, AREA_CHANGED);
 			chprintln(ch, "Reset added.");
 		}
-		else if (!str_cmp(arg2, "random") && is_number(arg3))
+		else if (!str_cmp(arg2, "random"))
 		{
-			if (atoi(arg3) < 1 || atoi(arg3) > 6)
+			int door;
+
+			if (is_number(arg3))
+			{
+				door = atoi(arg3);
+			}
+			else
+			{
+				if ((door = get_direction(arg3)) != -1)
+					door++;
+			}
+
+			if (door < 0 || door > 6)
 			{
 				chprintln(ch, "Invalid argument.");
 				return;
 			}
+
+			if (door == 0
+				&& (IS_NULLSTR(arg4) || !is_exact_name(arg4, "area world")))
+			{
+				chprintln(ch, "Invalid or missing argument.");
+				return;
+			}
+			if (is_exact_name(arg4, "area world") && door > 0
+				&& ch->in_room->exit[door - 1] != NULL)
+			{
+				chprintln(ch, "There is already an exit in that direction.");
+				return;
+			}
 			pReset = new_reset_data();
 			pReset->command = 'R';
 			pReset->arg1 = ch->in_room->vnum;
-			pReset->arg2 = atoi(arg3);
-			add_reset(ch->in_room, pReset, atol(arg1));
+			pReset->arg2 = door;
+			pReset->arg3 =
+				!str_cmp(arg4, "area") ? 1 : !str_cmp(arg4, "world") ? 2 : 0;
+			add_reset(ch->in_room, pReset, atoi(arg1));
 			SET_BIT(ch->in_room->area->area_flags, AREA_CHANGED);
-			chprintln(ch, "Random exits reset added.");
+			chprintln(ch, "Random exit reset added.");
 		}
 		else
 		{
@@ -2628,6 +2567,7 @@
 					  "        RESET <number> MOB <vnum> [max #x area] [max #x room]");
 			chprintln(ch, "        RESET <number> DELETE");
 			chprintln(ch, "        RESET <number> RANDOM [#x exits]");
+			chprintln(ch, "        RESET <number> RANDOM <exit|0> area|world");
 		}
 	}
 
@@ -2703,62 +2643,27 @@
 	chprintln(ch, "");
 }
 
-void *get_olc_show(int editor)
-{
-	switch (editor)
-	{
-	case ED_AREA:
-		return (void *) aedit_show;
-	case ED_ROOM:
-		return (void *) redit_show;
-	case ED_OBJECT:
-		return (void *) oedit_show;
-	case ED_MOBILE:
-		return (void *) medit_show;
-	case ED_MPCODE:
-		return (void *) mpedit_show;
-	case ED_HELP:
-		return (void *) hedit_show;
-	case ED_CLAN:
-		return (void *) cedit_show;
-	case ED_SOCIAL:
-		return (void *) sedit_show;
-	case ED_RACE:
-		return (void *) raedit_show;
-	case ED_SKILL:
-		return (void *) skedit_show;
-	case ED_GROUP:
-		return (void *) gredit_show;
-	case ED_CMD:
-		return (void *) cmdedit_show;
-	case ED_CLASS:
-		return (void *) cledit_show;
-	}
-	return NULL;
-}
-
 void edit_start(CHAR_DATA * ch, void *OLC, int Ed)
 {
-	bool new_ed = FALSE;
+	int old_ed;
 	OLC_FUN *olc_fun;
 
 	if (!ch || !ch->desc)
 		return;
 
-	if (ch->desc->editor != Ed)
-		new_ed = TRUE;
+	old_ed = ch->desc->editor;
 
-	ch->desc->pEdit = (void *) OLC;
+	ch->desc->pEdit = OLC;
 	ch->desc->editor = Ed;
-	if ((olc_fun = (OLC_FUN *) get_olc_show(ch->desc->editor)) != NULL)
-		(*olc_fun) (ch, "");
-	if (new_ed)
+	if (old_ed != Ed)
 	{
 		act("$n has entered the $t editor.", ch, olc_ed_name_long(ch), NULL,
 			TO_ROOM);
 		act("You are now entering the $t editor, type 'done' to finish.", ch,
 			olc_ed_name_long(ch), NULL, TO_CHAR);
 	}
+	if ((olc_fun = get_olc_show(ch->desc->editor)) != NULL)
+		(*olc_fun) (ch, "");
 }
 
 void autoset(MOB_INDEX_DATA * pMob)
diff -ur -x config -x o -x rom src/olc.h new/olc.h
--- src/olc.h	Tue May 27 02:46:36 2003
+++ new/olc.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /***************************************************************************
@@ -66,48 +66,35 @@
 /*
  * New typedefs.
  */
-typedef bool OLC_FUN args((CHAR_DATA * ch, const char *argument));
+typedef bool OLC_FUN(CHAR_DATA * ch, const char *argument);
+typedef const struct olc_ed_type OLCED_DATA;
 #define DECLARE_OLC_FUN( fun )	OLC_FUN    fun
+#define OLCED(fun)	bool fun(CHAR_DATA *ch, const char *argument)
 
 /*
  * Connected states for editor.
  */
-#define ED_NONE		0
-#define ED_AREA		1
-#define ED_ROOM		2
-#define ED_OBJECT	3
-#define ED_MOBILE	4
-#define ED_MPCODE	5
-#define ED_OPCODE       6
-#define ED_RPCODE       7
-#define ED_HELP		8
-#define ED_SOCIAL   9
-#define ED_CLAN     10
-#define ED_CMD      11
-#define ED_SKILL    12
-#define ED_GROUP    13
-#define ED_RACE     14
-#define ED_CLASS    15
-#define ED_DEITY    16
-
-/*
- * Interpreter Prototypes
- */
-void aedit args((CHAR_DATA * ch, char *argument));
-void redit args((CHAR_DATA * ch, char *argument));
-void medit args((CHAR_DATA * ch, char *argument));
-void oedit args((CHAR_DATA * ch, char *argument));
-void mpedit args((CHAR_DATA * ch, char *argument));
-void opedit args((CHAR_DATA * ch, char *argument));
-void rpedit args((CHAR_DATA * ch, char *argument));
-void hedit args((CHAR_DATA *, char *));
-void cedit args((CHAR_DATA * ch, char *argument));
-void cmdedit args((CHAR_DATA * ch, char *argument));
-void skedit args((CHAR_DATA * ch, char *argument));
-void gredit args((CHAR_DATA * ch, char *argument));
-void raedit args((CHAR_DATA * ch, char *argument));
-void cledit args((CHAR_DATA * ch, char *argument));
-void dedit args((CHAR_DATA * ch, char *argument));
+#define ED_NONE		-1
+#define ED_AREA		0
+#define ED_ROOM		1
+#define ED_OBJECT	2
+#define ED_MOBILE	3
+#define ED_MPCODE	4
+#define ED_OPCODE       5
+#define ED_RPCODE       6
+#define ED_HELP		7
+#define ED_SOCIAL   8
+#define ED_CLAN     9
+#define ED_CMD      10
+#define ED_SKILL    11
+#define ED_GROUP    12
+#define ED_RACE     13
+#define ED_CLASS    14
+#define ED_DEITY    15
+#define ED_CHAN		16
+#define ED_MUD      17
+#define ED_SONG     18
+#define ED_MAX		19
 
 /*
  * OLC Constants
@@ -123,89 +110,93 @@
 	void *argument;
 	ED_FUN *function;
 	const void *parameter;
+	VALIDATE_FUN *validate;
 };
 
-/*
- * Structure for an OLC editor startup command.
- */
-struct editor_cmd_type
+struct olc_ed_type
 {
-	char *const name;
+	const char *name;
+	const char *longname;
+	int ed;
+	OLC_FUN *show;
 	DO_FUN *do_fun;
+	const struct olc_comm_type *table;
 };
+EXTERN const struct olc_ed_type olc_ed_table[ED_MAX];
 
 /*
  * Utils.
  */
-AREA_DATA *get_vnum_area args((vnum_t vnum));
-AREA_DATA *get_area_data args((int vnum));
-void add_reset args((ROOM_INDEX_DATA * room, RESET_DATA * pReset, int pindex));
-void display_resets(CHAR_DATA * ch);
-
-void show_olc_cmds(CHAR_DATA * ch);
-bool oedit_values(CHAR_DATA * ch, const char *argument, int value);
-bool set_value(CHAR_DATA * ch, OBJ_INDEX_DATA * pObj, const char *argument,
-			   int value);
-bool set_obj_values(CHAR_DATA * ch, OBJ_INDEX_DATA * pObj, int value_num,
-					const char *argument);
-void show_obj_values(CHAR_DATA * ch, OBJ_INDEX_DATA * obj);
-bool change_exit(CHAR_DATA * ch, const char *argument, int door);
-bool check_range(long lower, long upper);
-void show_spec_cmds(CHAR_DATA * ch);
-void show_skill_cmds(CHAR_DATA * ch, int tar);
-flag_t wear_bit(int loc);
-int wear_loc(flag_t bits, int count);
-void save_area(AREA_DATA * pArea);
-void save_helps(void);
-void save_shops(FILE * fp, AREA_DATA * pArea);
-void save_resets(FILE * fp, AREA_DATA * pArea);
-void save_door_resets(FILE * fp, AREA_DATA * pArea);
-void save_specials(FILE * fp, AREA_DATA * pArea);
-void save_rooms(FILE * fp, AREA_DATA * pArea);
-void save_objects(FILE * fp, AREA_DATA * pArea);
-void save_object(FILE * fp, OBJ_INDEX_DATA * pObjIndex);
-void save_mobiles(FILE * fp, AREA_DATA * pArea);
-void save_mobile(FILE * fp, MOB_INDEX_DATA * pMobIndex);
-void save_mobprogs(FILE * fp, AREA_DATA * pArea);
-void save_area_list(void);
-char *fix_string(const char *str);
-void stop_editing(void *OLC);
-int calc_avedam(int num_dice, int dam_dice);
-void edit_start args((CHAR_DATA * ch, void *OLC, int Ed));
+PROTOTYPE(AREA_DATA * get_vnum_area, (vnum_t));
+PROTOTYPE(AREA_DATA * get_area_data, (int));
+PROTOTYPE(CHANNEL_DATA * get_chan_data, (int));
+PROTOTYPE(void add_reset, (ROOM_INDEX_DATA *, RESET_DATA *, int));
+PROTOTYPE(void display_resets, (CHAR_DATA *));
+
+PROTOTYPE(void show_olc_cmds, (CHAR_DATA *));
+PROTOTYPE(bool oedit_values, (CHAR_DATA *, const char *, int));
+PROTOTYPE(bool set_value, (CHAR_DATA *, OBJ_INDEX_DATA *, const char *, int));
+PROTOTYPE(bool set_obj_values, (CHAR_DATA *, OBJ_INDEX_DATA *, int,
+								const char *));
+PROTOTYPE(void show_obj_values, (CHAR_DATA *, OBJ_INDEX_DATA *));
+PROTOTYPE(bool change_exit, (CHAR_DATA *, const char *, int));
+PROTOTYPE(bool check_range, (long, long));
+PROTOTYPE(void show_spec_cmds, (CHAR_DATA *));
+PROTOTYPE(void show_skill_cmds, (CHAR_DATA *, int));
+PROTOTYPE(flag_t wear_bit, (wloc_t));
+PROTOTYPE(wloc_t wear_loc, (flag_t, int));
+PROTOTYPE(void save_area, (AREA_DATA *));
+PROTOTYPE(void save_helps, (void));
+PROTOTYPE(void save_shops, (FILE *, AREA_DATA *));
+PROTOTYPE(void save_resets, (FILE *, AREA_DATA *));
+PROTOTYPE(void save_door_resets, (FILE *, AREA_DATA *));
+PROTOTYPE(void save_specials, (FILE *, AREA_DATA *));
+PROTOTYPE(void save_rooms, (FILE *, AREA_DATA *));
+PROTOTYPE(void save_objects, (FILE *, AREA_DATA *));
+PROTOTYPE(void save_object, (FILE *, OBJ_INDEX_DATA *));
+PROTOTYPE(void save_mobiles, (FILE *, AREA_DATA *));
+PROTOTYPE(void save_mobile, (FILE *, MOB_INDEX_DATA *));
+PROTOTYPE(void save_mobprogs, (FILE *, AREA_DATA *));
+PROTOTYPE(void save_area_list, (void));
+PROTOTYPE(void stop_editing, (void *));
+PROTOTYPE(int calc_avedam, (int, int));
+PROTOTYPE(void edit_start, (CHAR_DATA *, void *, int));
 
 /*
  * Interpreter Table Prototypes
  */
-extern const struct olc_comm_type mob_olc_comm_table[];
-extern const struct olc_comm_type obj_olc_comm_table[];
-extern const struct olc_comm_type room_olc_comm_table[];
-extern const struct olc_comm_type area_olc_comm_table[];
-extern const struct olc_comm_type mprog_olc_comm_table[];
-extern const struct olc_comm_type oprog_olc_comm_table[];
-extern const struct olc_comm_type rprog_olc_comm_table[];
-extern const struct olc_comm_type help_olc_comm_table[];
-extern const struct olc_comm_type social_olc_comm_table[];
-extern const struct olc_comm_type clan_olc_comm_table[];
-extern const struct olc_comm_type cmd_olc_comm_table[];
-extern const struct olc_comm_type skill_olc_comm_table[];
-extern const struct olc_comm_type group_olc_comm_table[];
-extern const struct olc_comm_type race_olc_comm_table[];
-extern const struct olc_comm_type class_olc_comm_table[];
-extern const struct olc_comm_type deity_olc_comm_table[];
+EXTERN const struct olc_comm_type mob_olc_comm_table[];
+EXTERN const struct olc_comm_type obj_olc_comm_table[];
+EXTERN const struct olc_comm_type room_olc_comm_table[];
+EXTERN const struct olc_comm_type area_olc_comm_table[];
+EXTERN const struct olc_comm_type mprog_olc_comm_table[];
+EXTERN const struct olc_comm_type oprog_olc_comm_table[];
+EXTERN const struct olc_comm_type rprog_olc_comm_table[];
+EXTERN const struct olc_comm_type help_olc_comm_table[];
+EXTERN const struct olc_comm_type social_olc_comm_table[];
+EXTERN const struct olc_comm_type clan_olc_comm_table[];
+EXTERN const struct olc_comm_type cmd_olc_comm_table[];
+EXTERN const struct olc_comm_type skill_olc_comm_table[];
+EXTERN const struct olc_comm_type group_olc_comm_table[];
+EXTERN const struct olc_comm_type race_olc_comm_table[];
+EXTERN const struct olc_comm_type class_olc_comm_table[];
+EXTERN const struct olc_comm_type deity_olc_comm_table[];
+EXTERN const struct olc_comm_type chan_olc_comm_table[];
+EXTERN const struct olc_comm_type mud_olc_comm_table[];
+EXTERN const struct olc_comm_type song_olc_comm_table[];
 
 /*
  * General Functions
  */
-bool show_commands args((CHAR_DATA * ch, char *argument));
-bool show_help args((CHAR_DATA * ch, const char *argument));
-bool edit_done args((CHAR_DATA * ch));
-bool show_version args((CHAR_DATA * ch, char *argument));
+PROTOTYPE(bool show_commands, (CHAR_DATA *, char *));
+PROTOTYPE(bool show_help, (CHAR_DATA *, const char *));
+PROTOTYPE(bool edit_done, (CHAR_DATA *));
+PROTOTYPE(bool show_version, (CHAR_DATA *, char *));
 
-bool process_olc_command args((CHAR_DATA * ch, const char *argument,
-							   const struct olc_comm_type * table));
+PROTOTYPE(bool process_olc_command, (CHAR_DATA *, const char *,
+									 const struct olc_comm_type *));
 
 DECLARE_ED_FUN(olced_str);
-DECLARE_ED_FUN(olced_str_line);
 DECLARE_ED_FUN(olced_desc);
 DECLARE_ED_FUN(olced_bool);
 DECLARE_ED_FUN(olced_flag);
@@ -224,6 +215,19 @@
 DECLARE_ED_FUN(olced_poslookup);
 DECLARE_ED_FUN(olced_neglookup);
 DECLARE_ED_FUN(olced_vnum);
+DECLARE_ED_FUN(olced_addprog);
+DECLARE_ED_FUN(olced_delprog);
+DECLARE_ED_FUN(olced_array);
+DECLARE_ED_FUN(olced_larray);
+DECLARE_ED_FUN(olced_sarray);
+DECLARE_ED_FUN(olced_farray);
+DECLARE_ED_FUN(olced_mclass);
+DECLARE_ED_FUN(olced_stance);
+DECLARE_ED_FUN(olced_stats);
+DECLARE_ED_FUN(olced_deity);
+DECLARE_ED_FUN(olced_getchar);
+DECLARE_ED_FUN(olced_time);
+DECLARE_ED_FUN(olced_vnum);
 
 DECLARE_VALIDATE_FUN(validate_align);
 DECLARE_VALIDATE_FUN(validate_level);
@@ -246,6 +250,7 @@
 DECLARE_OLC_FUN(aedit_vnum);
 DECLARE_OLC_FUN(aedit_lvnum);
 DECLARE_OLC_FUN(aedit_uvnum);
+DECLARE_OLC_FUN(aedit_climate);
 
 /*
  * Room Editor Prototypes
@@ -262,8 +267,6 @@
 DECLARE_OLC_FUN(redit_clan);
 DECLARE_OLC_FUN(redit_delete);
 DECLARE_OLC_FUN(redit_format);
-DECLARE_OLC_FUN(redit_addrprog);
-DECLARE_OLC_FUN(redit_delrprog);
 
 /*
  * Object Editor Prototypes
@@ -274,8 +277,6 @@
 DECLARE_OLC_FUN(oedit_addapply);
 DECLARE_OLC_FUN(oedit_delaffect);
 DECLARE_OLC_FUN(oedit_delete);
-DECLARE_OLC_FUN(oedit_addoprog);
-DECLARE_OLC_FUN(oedit_deloprog);
 DECLARE_OLC_FUN(oedit_autoweapon);
 DECLARE_OLC_FUN(oedit_autoarmor);
 
@@ -286,8 +287,6 @@
 DECLARE_OLC_FUN(medit_create);
 DECLARE_OLC_FUN(medit_delete);
 DECLARE_OLC_FUN(medit_group);	/* ROM */
-DECLARE_OLC_FUN(medit_addmprog);	/* ROM */
-DECLARE_OLC_FUN(medit_delmprog);	/* ROM */
 DECLARE_OLC_FUN(medit_autoset);
 DECLARE_OLC_FUN(medit_autoeasy);
 DECLARE_OLC_FUN(medit_autohard);
@@ -368,6 +367,20 @@
 DECLARE_OLC_FUN(dedit_delete);
 DECLARE_OLC_FUN(dedit_create);
 
+DECLARE_OLC_FUN(chanedit_show);
+DECLARE_OLC_FUN(chanedit_create);
+DECLARE_OLC_FUN(chanedit_gcn);
+DECLARE_OLC_FUN(chanedit_delete);
+DECLARE_OLC_FUN(chanedit_colour);
+DECLARE_OLC_FUN(chanedit_list);
+
+DECLARE_OLC_FUN(mudedit_show);
+
+DECLARE_OLC_FUN(songedit_show);
+DECLARE_OLC_FUN(songedit_lyrics);
+DECLARE_OLC_FUN(songedit_create);
+DECLARE_OLC_FUN(songedit_delete);
+
 /*
  * Macros
  */
@@ -390,42 +403,43 @@
 #define EDIT_RACE(ch, race) ( race = (RACE_DATA *) ch->desc->pEdit )
 #define EDIT_CLASS(ch, class) ( class = (CLASS_DATA *) ch->desc->pEdit )
 #define EDIT_DEITY(ch, deity)   (deity = (DEITY_DATA *)ch->desc->pEdit)
+#define EDIT_CHAN(ch, chan)		(chan = (CHANNEL_DATA *)ch->desc->pEdit)
+#define EDIT_MUD(ch, mud)       (mud = (MUD *)ch->desc->pEdit)
+#define EDIT_SONG(ch, song)     (song = (SONG_DATA *)ch->desc->pEdit)
 
 /*
  * Prototypes
  */
 /* mem.c - memory prototypes. */
 #define ED	EXTRA_DESCR_DATA
-RESET_DATA *new_reset_data args((void));
-void free_reset_data args((RESET_DATA * pReset));
-AREA_DATA *new_area args((void));
-void free_area args((AREA_DATA * pArea));
-EXIT_DATA *new_exit args((void));
-void free_exit args((EXIT_DATA * pExit));
-ROOM_INDEX_DATA *new_room_index args((void));
-void free_room_index args((ROOM_INDEX_DATA * pRoom));
-SHOP_DATA *new_shop args((void));
-void free_shop args((SHOP_DATA * pShop));
-OBJ_INDEX_DATA *new_obj_index args((void));
-void free_obj_index args((OBJ_INDEX_DATA * pObj));
-MOB_INDEX_DATA *new_mob_index args((void));
-void free_mob_index args((MOB_INDEX_DATA * pMob));
+PROTOTYPE(RESET_DATA * new_reset_data, (void));
+PROTOTYPE(void free_reset_data, (RESET_DATA *));
+PROTOTYPE(AREA_DATA * new_area, (void));
+PROTOTYPE(void free_area, (AREA_DATA *));
+PROTOTYPE(EXIT_DATA * new_exit, (void));
+PROTOTYPE(void free_exit, (EXIT_DATA *));
+PROTOTYPE(ROOM_INDEX_DATA * new_room_index, (void));
+PROTOTYPE(void free_room_index, (ROOM_INDEX_DATA *));
+PROTOTYPE(SHOP_DATA * new_shop, (void));
+PROTOTYPE(void free_shop, (SHOP_DATA *));
+PROTOTYPE(OBJ_INDEX_DATA * new_obj_index, (void));
+PROTOTYPE(void free_obj_index, (OBJ_INDEX_DATA *));
+PROTOTYPE(MOB_INDEX_DATA * new_mob_index, (void));
+PROTOTYPE(void free_mob_index, (MOB_INDEX_DATA *));
 #undef	ED
 
-void show_liqlist args((CHAR_DATA * ch));
-void show_damlist args((CHAR_DATA * ch));
+PROTOTYPE(void show_liqlist, (CHAR_DATA *));
+PROTOTYPE(void show_damlist, (CHAR_DATA *));
 
-PROG_LIST *new_prog args((void));
-void free_prog args((PROG_LIST * mp));
-PROG_CODE *new_pcode args((void));
-void free_pcode args((PROG_CODE * pCode));
-
-void sedit args((CHAR_DATA * ch, char *argument));
-
-void autoset args((MOB_INDEX_DATA * pMob));
-void autohard args((MOB_INDEX_DATA * pMob));
-void autoeasy args((MOB_INDEX_DATA * pMob));
-void autoarmor args((OBJ_INDEX_DATA * pObj));
-void autoweapon args((OBJ_INDEX_DATA * pObj));
+PROTOTYPE(PROG_LIST * new_prog, (void));
+PROTOTYPE(void free_prog, (PROG_LIST *));
+PROTOTYPE(PROG_CODE * new_pcode, (void));
+PROTOTYPE(void free_pcode, (PROG_CODE *));
+
+PROTOTYPE(void autoset, (MOB_INDEX_DATA *));
+PROTOTYPE(void autohard, (MOB_INDEX_DATA *));
+PROTOTYPE(void autoeasy, (MOB_INDEX_DATA *));
+PROTOTYPE(void autoarmor, (OBJ_INDEX_DATA *));
+PROTOTYPE(void autoweapon, (OBJ_INDEX_DATA *));
 
 #endif
diff -ur -x config -x o -x rom src/olc_act.c new/olc_act.c
--- src/olc_act.c	Tue May 27 02:46:36 2003
+++ new/olc_act.c	Sun Aug 31 19:23:20 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /***************************************************************************
@@ -38,12 +38,6 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "tables.h"
 #include "olc.h"
@@ -64,13 +58,6 @@
 		TOGGLE_BIT(_blargh, UMAX(0, blah));	\
 	}
 
-/* Return TRUE if area changed, FALSE if not. */
-#define REDIT( fun )		bool fun( CHAR_DATA *ch, const char *argument )
-#define OEDIT( fun )		bool fun( CHAR_DATA *ch, const char *argument )
-#define MEDIT( fun )		bool fun( CHAR_DATA *ch, const char *argument )
-#define AEDIT( fun )		bool fun( CHAR_DATA *ch, const char *argument )
-#define CEDIT( fun )        bool fun( CHAR_DATA *ch, const char *argument )
-
 struct olc_help_type
 {
 	char *command;
@@ -181,28 +168,19 @@
  ****************************************************************************/
 void show_flag_cmds(CHAR_DATA * ch, const struct flag_type *flag_table)
 {
-	char buf[MAX_STRING_LENGTH];
-	char buf1[MAX_STRING_LENGTH];
 	int flag;
-	int col;
+	init_cols(ch, 4);
 
-	buf1[0] = '\0';
-	col = 0;
 	for (flag = 0; flag_table[flag].name != NULL; flag++)
 	{
 		if (flag_table[flag].settable)
 		{
-			sprintf(buf, "%-19.18s", flag_table[flag].name);
-			strcat(buf1, buf);
-			if (++col % 4 == 0)
-				strcat(buf1, "\n\r");
+			print_cols(chprint, ch, flag_table[flag].name);
 		}
 	}
 
-	if (col % 4 != 0)
-		strcat(buf1, "\n\r");
-
-	chprint(ch, buf1);
+	if (!done_newline)
+		chprintln(ch, "");
 	return;
 }
 
@@ -215,15 +193,11 @@
  		(2) Adding a check for a level range.
  Called by:	show_help(olc_act.c).
  ****************************************************************************/
-void show_skill_cmds(CHAR_DATA * ch, int tar)
+void show_skill_cmds(CHAR_DATA * ch, tar_t tar)
 {
-	char buf[MAX_STRING_LENGTH];
-	char buf1[MAX_STRING_LENGTH * 2];
 	int sn;
-	int col;
+	init_cols(ch, 4);
 
-	buf1[0] = '\0';
-	col = 0;
 	for (sn = 0; sn < maxSkill; sn++)
 	{
 		if (!skill_table[sn].name)
@@ -233,19 +207,14 @@
 			skill_table[sn].spell_fun == spell_null)
 			continue;
 
-		if (tar == -1 || skill_table[sn].target == tar)
+		if (tar == TAR_NONE || skill_table[sn].target == tar)
 		{
-			sprintf(buf, "%-19.18s", skill_table[sn].name);
-			strcat(buf1, buf);
-			if (++col % 4 == 0)
-				strcat(buf1, "\n\r");
+			print_cols(chprint, ch, skill_table[sn].name);
 		}
 	}
 
-	if (col % 4 != 0)
-		strcat(buf1, "\n\r");
-
-	chprint(ch, buf1);
+	if (!done_newline)
+		chprintln(ch, "");
 	return;
 }
 
@@ -256,26 +225,17 @@
  ****************************************************************************/
 void show_spec_cmds(CHAR_DATA * ch)
 {
-	char buf[MAX_STRING_LENGTH];
-	char buf1[MAX_STRING_LENGTH];
 	int spec;
-	int col;
+	init_cols(ch, 4);
 
-	buf1[0] = '\0';
-	col = 0;
 	chprintln(ch, "Preceed special functions with 'spec_'\n\r");
 	for (spec = 0; spec_table[spec].function != NULL; spec++)
 	{
-		sprintf(buf, "%-19.18s", &spec_table[spec].name[5]);
-		strcat(buf1, buf);
-		if (++col % 4 == 0)
-			strcat(buf1, "\n\r");
+		print_cols(chprint, ch, &spec_table[spec].name[5]);
 	}
 
-	if (col % 4 != 0)
-		strcat(buf1, "\n\r");
-
-	chprint(ch, buf1);
+	if (!done_newline)
+		chprintln(ch, "");
 	return;
 }
 
@@ -296,7 +256,7 @@
 	/*
 	 * Display syntax.
 	 */
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Syntax:  ? [command]\n\r");
 		chprintln(ch, "[command]  [description]");
@@ -336,7 +296,7 @@
 			else if (help_table[cnt].structure == skill_table)
 			{
 
-				if (spell[0] == '\0')
+				if (IS_NULLSTR(spell))
 				{
 					chprintln(ch, "Syntax:  ? spells "
 							  "[ignore/attack/defend/self/object/all]");
@@ -344,7 +304,7 @@
 				}
 
 				if (!str_prefix(spell, "all"))
-					show_skill_cmds(ch, -1);
+					show_skill_cmds(ch, TAR_NONE);
 				else if (!str_prefix(spell, "ignore"))
 					show_skill_cmds(ch, TAR_IGNORE);
 				else if (!str_prefix(spell, "attack"))
@@ -374,7 +334,7 @@
 	return FALSE;
 }
 
-REDIT(redit_format)
+OLCED(redit_format)
 {
 	ROOM_INDEX_DATA *pRoom;
 
@@ -386,11 +346,10 @@
 	return TRUE;
 }
 
-REDIT(redit_rlist)
+OLCED(redit_rlist)
 {
 	ROOM_INDEX_DATA *pRoomIndex;
 	AREA_DATA *pArea;
-	char buf[MAX_STRING_LENGTH];
 	BUFFER *buf1;
 	char arg[MAX_INPUT_LENGTH];
 	bool found;
@@ -409,10 +368,10 @@
 		if ((pRoomIndex = get_room_index(vnum)))
 		{
 			found = TRUE;
-			sprintf(buf, "[%5ld] %-17.16s", vnum, capitalize(pRoomIndex->name));
-			add_buf(buf1, buf);
+			bprintf(buf1, "[%5ld] %-17.16s", vnum,
+					capitalize(pRoomIndex->name));
 			if (++col % 3 == 0)
-				add_buf(buf1, "\n\r");
+				bprintln(buf1, "");
 		}
 	}
 
@@ -423,18 +382,17 @@
 	}
 
 	if (col % 3 != 0)
-		add_buf(buf1, "\n\r");
+		bprintln(buf1, "");
 
-	page_to_char(buf_string(buf1), ch);
+	sendpage(ch, buf_string(buf1));
 	free_buf(buf1);
 	return FALSE;
 }
 
-REDIT(redit_mlist)
+OLCED(redit_mlist)
 {
 	MOB_INDEX_DATA *pMobIndex;
 	AREA_DATA *pArea;
-	char buf[MAX_STRING_LENGTH];
 	BUFFER *buf1;
 	char arg[MAX_INPUT_LENGTH];
 	bool fAll, found;
@@ -442,7 +400,7 @@
 	int col = 0;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Syntax:  mlist <all/name>");
 		return FALSE;
@@ -461,11 +419,10 @@
 			if (fAll || is_name(arg, pMobIndex->player_name))
 			{
 				found = TRUE;
-				sprintf(buf, "[%5ld] %-17.16s", pMobIndex->vnum,
+				bprintf(buf1, "[%5ld] %-17.16s", pMobIndex->vnum,
 						capitalize(pMobIndex->short_descr));
-				add_buf(buf1, buf);
 				if (++col % 3 == 0)
-					add_buf(buf1, "\n\r");
+					bprintln(buf1, "");
 			}
 		}
 	}
@@ -477,14 +434,14 @@
 	}
 
 	if (col % 3 != 0)
-		add_buf(buf1, "\n\r");
+		bprintln(buf1, "");
 
-	page_to_char(buf_string(buf1), ch);
+	sendpage(ch, buf_string(buf1));
 	free_buf(buf1);
 	return FALSE;
 }
 
-REDIT(redit_delete)
+OLCED(redit_delete)
 {
 	ROOM_INDEX_DATA *pRoom, *pRoom2;
 	RESET_DATA *pReset;
@@ -642,11 +599,10 @@
 	return TRUE;
 }
 
-REDIT(redit_olist)
+OLCED(redit_olist)
 {
 	OBJ_INDEX_DATA *pObjIndex;
 	AREA_DATA *pArea;
-	char buf[MAX_STRING_LENGTH];
 	BUFFER *buf1;
 	char arg[MAX_INPUT_LENGTH];
 	bool fAll, found;
@@ -654,7 +610,7 @@
 	int col = 0;
 
 	one_argument(argument, arg);
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Syntax:  olist <all/name/item_type>");
 		return FALSE;
@@ -674,11 +630,10 @@
 				(int) flag_value(type_flags, arg) == pObjIndex->item_type)
 			{
 				found = TRUE;
-				sprintf(buf, "[%5ld] %-17.16s", pObjIndex->vnum,
+				bprintf(buf1, "[%5ld] %-17.16s", pObjIndex->vnum,
 						capitalize(pObjIndex->short_descr));
-				add_buf(buf1, buf);
 				if (++col % 3 == 0)
-					add_buf(buf1, "\n\r");
+					bprintln(buf1, "");
 			}
 		}
 	}
@@ -690,19 +645,19 @@
 	}
 
 	if (col % 3 != 0)
-		add_buf(buf1, "\n\r");
+		bprintln(buf1, "");
 
-	page_to_char(buf_string(buf1), ch);
+	sendpage(ch, buf_string(buf1));
 	free_buf(buf1);
 	return FALSE;
 }
 
-REDIT(redit_mshow)
+OLCED(redit_mshow)
 {
 	MOB_INDEX_DATA *pMob;
 	vnum_t value;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Syntax:  mshow <vnum>");
 		return FALSE;
@@ -731,12 +686,12 @@
 	return FALSE;
 }
 
-REDIT(redit_oshow)
+OLCED(redit_oshow)
 {
 	OBJ_INDEX_DATA *pObj;
 	vnum_t value;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Syntax:  oshow <vnum>");
 		return FALSE;
@@ -806,24 +761,14 @@
 /*
  * Area Editor Functions.
  */
-AEDIT(aedit_show)
+OLCED(aedit_show)
 {
 	AREA_DATA *pArea;
 
 	EDIT_AREA(ch, pArea);
 
-	chprintf(ch, "%s\n\r",
-			 stringf(ch, 0, ALIGN_CENTER, "-",
-					 FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
-
 	chprintlnf(ch, "Name:     [%5d] %s", pArea->vnum, pArea->name);
 
-#if 0							/* ROM OLC */
-	chprintlnf(ch, "Recall:   [%5d] %s", pArea->recall,
-			   get_room_index(pArea->recall) ? get_room_index(pArea->recall)->
-			   name : "none");
-#endif							/* ROM */
-
 	chprintlnf(ch, "File:     %s", pArea->file_name);
 
 	chprintlnf(ch, "Vnums:    [%ld-%ld]", pArea->min_vnum, pArea->max_vnum);
@@ -838,14 +783,18 @@
 
 	chprintlnf(ch, "Credits : [%s]", pArea->credits);
 
+	chprintlnf(ch, "Climate : Temp [%s], Precip [%s], Wind [%s]",
+			   temp_settings[pArea->weather.climate_temp],
+			   precip_settings[pArea->weather.climate_precip],
+			   wind_settings[pArea->weather.climate_wind]);
+
 	chprintlnf(ch, "Flags:    [%s]",
 			   flag_string(area_flags, pArea->area_flags));
-	chprintln(ch, draw_line(ch, NULL, 0));
 
 	return FALSE;
 }
 
-AEDIT(aedit_reset)
+OLCED(aedit_reset)
 {
 	AREA_DATA *pArea;
 
@@ -857,7 +806,7 @@
 	return FALSE;
 }
 
-AEDIT(aedit_create)
+OLCED(aedit_create)
 {
 	AREA_DATA *pArea;
 
@@ -870,7 +819,7 @@
 	return FALSE;
 }
 
-AEDIT(aedit_file)
+OLCED(aedit_file)
 {
 	AREA_DATA *pArea;
 	char file[MAX_STRING_LENGTH];
@@ -880,7 +829,7 @@
 
 	one_argument(argument, file);	/* Forces Lowercase */
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Syntax:  filename [$file]");
 		return FALSE;
@@ -908,15 +857,13 @@
 		}
 	}
 
-	free_string(pArea->file_name);
-	strcat(file, ".are");
-	pArea->file_name = str_dup(file);
+	replace_string(pArea->file_name, file);
 
 	chprintln(ch, "Filename set.");
 	return TRUE;
 }
 
-AEDIT(aedit_builder)
+OLCED(aedit_builder)
 {
 	AREA_DATA *pArea;
 	char name[MAX_STRING_LENGTH];
@@ -926,7 +873,7 @@
 
 	one_argument(argument, name);
 
-	if (name[0] == '\0')
+	if (IS_NULLSTR(name))
 	{
 		chprintln(ch, "Syntax:  builder [$name]  -toggles builder");
 		chprintln(ch, "Syntax:  builder All      -allows everyone");
@@ -940,10 +887,9 @@
 		pArea->builders = string_replace(pArea->builders, name, "\0");
 		pArea->builders = string_unpad(pArea->builders);
 
-		if (pArea->builders[0] == '\0')
+		if (IS_NULLSTR(pArea->builders))
 		{
-			free_string(pArea->builders);
-			pArea->builders = str_dup("None");
+			replace_string(pArea->builders, "None");
 		}
 		chprintln(ch, "Builder removed.");
 		return TRUE;
@@ -957,7 +903,7 @@
 			pArea->builders = string_unpad(pArea->builders);
 		}
 
-		if (pArea->builders[0] != '\0')
+		if (!IS_NULLSTR(pArea->builders))
 		{
 			strcat(buf, pArea->builders);
 			strcat(buf, " ");
@@ -974,7 +920,7 @@
 	return FALSE;
 }
 
-AEDIT(aedit_vnum)
+OLCED(aedit_vnum)
 {
 	AREA_DATA *pArea;
 	char lower[MAX_STRING_LENGTH];
@@ -987,8 +933,8 @@
 	argument = one_argument(argument, lower);
 	one_argument(argument, upper);
 
-	if (!is_number(lower) || lower[0] == '\0' || !is_number(upper) ||
-		upper[0] == '\0')
+	if (!is_number(lower) || IS_NULLSTR(lower) || !is_number(upper) ||
+		IS_NULLSTR(upper))
 	{
 		chprintln(ch, "Syntax:  vnum [#xlower] [#xupper]");
 		return FALSE;
@@ -1033,7 +979,7 @@
 	return TRUE;
 }
 
-AEDIT(aedit_lvnum)
+OLCED(aedit_lvnum)
 {
 	AREA_DATA *pArea;
 	char lower[MAX_STRING_LENGTH];
@@ -1044,7 +990,7 @@
 
 	one_argument(argument, lower);
 
-	if (!is_number(lower) || lower[0] == '\0')
+	if (!is_number(lower) || IS_NULLSTR(lower))
 	{
 		chprintln(ch, "Syntax:  min_vnum [#xlower]");
 		return FALSE;
@@ -1079,7 +1025,7 @@
 	return TRUE;
 }
 
-AEDIT(aedit_uvnum)
+OLCED(aedit_uvnum)
 {
 	AREA_DATA *pArea;
 	char upper[MAX_STRING_LENGTH];
@@ -1090,7 +1036,7 @@
 
 	one_argument(argument, upper);
 
-	if (!is_number(upper) || upper[0] == '\0')
+	if (!is_number(upper) || IS_NULLSTR(upper))
 	{
 		chprintln(ch, "Syntax:  max_vnum [#xupper]");
 		return FALSE;
@@ -1123,7 +1069,7 @@
 /*
  * Room Editor Functions.
  */
-REDIT(redit_show)
+OLCED(redit_show)
 {
 	ROOM_INDEX_DATA *pRoom;
 	char buf[MAX_STRING_LENGTH];
@@ -1138,9 +1084,6 @@
 
 	buf1[0] = '\0';
 
-	strcat(buf1,
-		   stringf(ch, 0, ALIGN_CENTER, "-",
-				   FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
 	strcat(buf1, "\n\r");
 
 	sprintf(buf, "Description:\n\r%s", pRoom->description);
@@ -1261,7 +1204,7 @@
 			{
 				state = one_argument((char *) state, word);
 
-				if (word[0] == '\0')
+				if (IS_NULLSTR(word))
 				{
 					int end;
 
@@ -1281,12 +1224,12 @@
 				strcat(buf1, " ");
 			}
 
-			if (pexit->keyword && pexit->keyword[0] != '\0')
+			if (!IS_NULLSTR(pexit->keyword))
 			{
 				sprintf(buf, "Kwds: [%s]\n\r", pexit->keyword);
 				strcat(buf1, buf);
 			}
-			if (pexit->description && pexit->description[0] != '\0')
+			if (!IS_NULLSTR(pexit->description))
 			{
 				sprintf(buf, "%s", pexit->description);
 				strcat(buf1, buf);
@@ -1294,7 +1237,6 @@
 		}
 	}
 
-	strcat(buf1, draw_line(ch, NULL, 0));
 	chprintln(ch, buf1);
 	if (pRoom->first_rprog)
 	{
@@ -1320,6 +1262,18 @@
 	return FALSE;
 }
 
+bool check_reset_exit(ROOM_INDEX_DATA * pRoom, int door)
+{
+	RESET_DATA *pReset;
+
+	for (pReset = pRoom->reset_first; pReset; pReset = pReset->next)
+	{
+		if (reset_door(pReset, FALSE) == door)
+			return TRUE;
+	}
+	return FALSE;
+}
+
 /* Local function. */
 bool change_exit(CHAR_DATA * ch, const char *argument, int door)
 {
@@ -1374,7 +1328,7 @@
 	argument = one_argument(argument, command);
 	one_argument(argument, arg);
 
-	if (command[0] == '\0' && argument[0] == '\0')	/* Move command. */
+	if (IS_NULLSTR(command) && IS_NULLSTR(argument))	/* Move command. */
 	{
 		move_char(ch, door, TRUE);	/* ROM OLC */
 		return FALSE;
@@ -1424,7 +1378,14 @@
 		EXIT_DATA *pExit;
 		ROOM_INDEX_DATA *toRoom;
 
-		if (arg[0] == '\0' || !is_number(arg))
+		if (check_reset_exit(pRoom, door))
+		{
+			chprintln(ch,
+					  "There is a random exit reset already using that direction.");
+			return FALSE;
+		}
+
+		if (IS_NULLSTR(arg) || !is_number(arg))
 		{
 			chprintln(ch, "Syntax:  [direction] link [vnum]");
 			return FALSE;
@@ -1470,7 +1431,14 @@
 	{
 		char buf[MAX_STRING_LENGTH];
 
-		if (arg[0] == '\0' || !is_number(arg))
+		if (check_reset_exit(pRoom, door))
+		{
+			chprintln(ch,
+					  "There is a random exit reset already using that direction.");
+			return FALSE;
+		}
+
+		if (IS_NULLSTR(arg) || !is_number(arg))
 		{
 			chprintln(ch, "Syntax: [direction] dig <vnum>");
 			return FALSE;
@@ -1486,7 +1454,14 @@
 	{
 		ROOM_INDEX_DATA *toRoom;
 
-		if (arg[0] == '\0' || !is_number(arg))
+		if (check_reset_exit(pRoom, door))
+		{
+			chprintln(ch,
+					  "There is a random exit reset already using that direction.");
+			return FALSE;
+		}
+
+		if (IS_NULLSTR(arg) || !is_number(arg))
 		{
 			chprintln(ch, "Syntax:  [direction] room [vnum]");
 			return FALSE;
@@ -1514,7 +1489,7 @@
 	{
 		OBJ_INDEX_DATA *key;
 
-		if (arg[0] == '\0' || !is_number(arg))
+		if (IS_NULLSTR(arg) || !is_number(arg))
 		{
 			chprintln(ch, "Syntax:  [direction] key [vnum]");
 			return FALSE;
@@ -1548,7 +1523,7 @@
 
 	if (!str_cmp(command, "name"))
 	{
-		if (arg[0] == '\0')
+		if (IS_NULLSTR(arg))
 		{
 			chprintln(ch, "Syntax:  [direction] name [string]");
 			chprintln(ch, "         [direction] name none");
@@ -1561,12 +1536,10 @@
 			return FALSE;
 		}
 
-		free_string(pRoom->exit[door]->keyword);
-
 		if (str_cmp(arg, "none"))
-			pRoom->exit[door]->keyword = str_dup(arg);
+			replace_string(pRoom->exit[door]->keyword, arg);
 		else
-			pRoom->exit[door]->keyword = str_dup("");
+			replace_string(pRoom->exit[door]->keyword, "");
 
 		chprintln(ch, "Exit name set.");
 		return TRUE;
@@ -1574,7 +1547,7 @@
 
 	if (!str_prefix(command, "description"))
 	{
-		if (arg[0] == '\0')
+		if (IS_NULLSTR(arg))
 		{
 			if (!pRoom->exit[door])
 			{
@@ -1593,7 +1566,7 @@
 	return FALSE;
 }
 
-REDIT(redit_create)
+OLCED(redit_create)
 {
 	AREA_DATA *pArea;
 	ROOM_INDEX_DATA *pRoom;
@@ -1604,7 +1577,7 @@
 
 	value = atol(argument);
 
-	if (argument[0] == '\0' || value <= 0)
+	if (IS_NULLSTR(argument) || value <= 0)
 	{
 		chprintln(ch, "Syntax:  create [vnum > 0]");
 		return FALSE;
@@ -1643,7 +1616,7 @@
 	return TRUE;
 }
 
-REDIT(redit_clan)
+OLCED(redit_clan)
 {
 	ROOM_INDEX_DATA *pRoom;
 
@@ -1655,7 +1628,7 @@
 	return TRUE;
 }
 
-REDIT(redit_mreset)
+OLCED(redit_mreset)
 {
 	ROOM_INDEX_DATA *pRoom;
 	MOB_INDEX_DATA *pMobIndex;
@@ -1670,7 +1643,7 @@
 	argument = one_argument(argument, arg);
 	argument = one_argument(argument, arg2);
 
-	if (arg[0] == '\0' || !is_number(arg))
+	if (IS_NULLSTR(arg) || !is_number(arg))
 	{
 		chprintln(ch, "Syntax:  mreset <vnum> <max #x> <mix #x>");
 		return FALSE;
@@ -1749,17 +1722,17 @@
  		1 = first match, 2 = second match etc.
  Called by:	oedit_reset(olc_act.c).
  ****************************************************************************/
-int wear_loc(flag_t bits, int count)
+wloc_t wear_loc(flag_t bits, int count)
 {
 	int flag;
 
 	for (flag = 0; wear_table[flag].wear_bit != -2; flag++)
 	{
 		if (IS_SET(bits, wear_table[flag].wear_bit) && --count < 1)
-			return wear_table[flag].wear_loc;
+			return (wloc_t) wear_table[flag].wear_loc;
 	}
 
-	return 0;
+	return WEAR_NONE;
 }
 
 /*****************************************************************************
@@ -1767,7 +1740,7 @@
  Purpose:	Converts a wear_loc into a bit.
  Called by:	redit_oreset(olc_act.c).
  ****************************************************************************/
-flag_t wear_bit(int loc)
+flag_t wear_bit(wloc_t loc)
 {
 	int flag;
 
@@ -1780,7 +1753,7 @@
 	return 0;
 }
 
-REDIT(redit_oreset)
+OLCED(redit_oreset)
 {
 	ROOM_INDEX_DATA *pRoom;
 	OBJ_INDEX_DATA *pObjIndex;
@@ -1798,7 +1771,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0' || !is_number(arg1))
+	if (IS_NULLSTR(arg1) || !is_number(arg1))
 	{
 		chprintln(ch, "Syntax:  oreset <vnum> <args>");
 		chprintln(ch, "        -no_args               = into room");
@@ -1822,7 +1795,7 @@
 	/*
 	 * Load into room.
 	 */
-	if (arg2[0] == '\0')
+	if (IS_NULLSTR(arg2))
 	{
 		pReset = new_reset_data();
 		pReset->command = 'O';
@@ -1843,7 +1816,7 @@
 		/*
 		 * Load into object's inventory.
 		 */
-		if (argument[0] == '\0' &&
+		if (IS_NULLSTR(argument) &&
 			((to_obj = get_obj_list(ch, arg2, pRoom->first_content)) != NULL))
 	{
 		pReset = new_reset_data();
@@ -1871,12 +1844,13 @@
 		 */
 	if ((to_mob = get_char_room(ch, NULL, arg2)) != NULL)
 	{
-		int pwear_loc = -1;
+		wloc_t pwear_loc = WEAR_NONE;
 
 		/*
 		 * Make sure the location on mobile is valid.
 		 */
-		if ((pwear_loc = flag_value(wear_loc_flags, argument)) == NO_FLAG)
+		if ((pwear_loc = (wloc_t) flag_value(wear_loc_flags, argument)) ==
+			NO_FLAG)
 		{
 			chprintln(ch, "REdit: Invalid wear_loc.  '? wear-loc'");
 			return FALSE;
@@ -1959,7 +1933,7 @@
 
 		obj_to_char(newobj, to_mob);
 		if (pReset->command == 'E')
-			equip_char(to_mob, newobj, pReset->arg3);
+			equip_char(to_mob, newobj, (wloc_t) pReset->arg3);
 
 		chprintlnf(ch,
 				   "%s (%ld) has been loaded "
@@ -2454,7 +2428,7 @@
 	return TRUE;
 }
 
-OEDIT(oedit_show)
+OLCED(oedit_show)
 {
 	OBJ_INDEX_DATA *pObj;
 	AFFECT_DATA *paf;
@@ -2463,10 +2437,6 @@
 
 	EDIT_OBJ(ch, pObj);
 
-	chprintf(ch, "%s\n\r",
-			 stringf(ch, 0, ALIGN_CENTER, "-",
-					 FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
-
 	chprintlnf(ch, "Name:        [%s]\n\rArea:        [%5d] %s",
 			   pObj->name, !pObj->area ? -1 : pObj->area->vnum,
 			   !pObj->area ? "No Area" : pObj->area->name);
@@ -2524,7 +2494,6 @@
 
 	show_obj_values(ch, pObj);
 
-	chprintln(ch, draw_line(ch, NULL, 0));
 	if (pObj->first_oprog)
 	{
 		int cnt;
@@ -2551,9 +2520,9 @@
 /*
  * Need to issue warning if flag_t isn't valid. -- does so now -- Hugin.
  */
-OEDIT(oedit_addaffect)
+OLCED(oedit_addaffect)
 {
-	int value;
+	apply_t value;
 	OBJ_INDEX_DATA *pObj;
 	AFFECT_DATA *pAf;
 	char loc[MAX_STRING_LENGTH];
@@ -2564,13 +2533,13 @@
 	argument = one_argument(argument, loc);
 	one_argument(argument, mod);
 
-	if (loc[0] == '\0' || mod[0] == '\0' || !is_number(mod))
+	if (IS_NULLSTR(loc) || IS_NULLSTR(mod) || !is_number(mod))
 	{
 		chprintln(ch, "Syntax:  addaffect [location] [#xmod]");
 		return FALSE;
 	}
 
-	if ((value = flag_value(apply_flags, loc)) == NO_FLAG)	/* Hugin */
+	if ((value = (apply_t) flag_value(apply_flags, loc)) == NO_FLAG)	/* Hugin */
 	{
 		chprintln(ch, "Valid affects are:");
 		show_help(ch, "apply");
@@ -2591,7 +2560,7 @@
 	return TRUE;
 }
 
-OEDIT(oedit_delete)
+OLCED(oedit_delete)
 {
 	OBJ_DATA *obj, *obj_next;
 	OBJ_INDEX_DATA *pObj;
@@ -2715,9 +2684,10 @@
 	return TRUE;
 }
 
-OEDIT(oedit_addapply)
+OLCED(oedit_addapply)
 {
-	int value, typ;
+	apply_t value;
+	where_t typ;
 	flag_t bv;
 	OBJ_INDEX_DATA *pObj;
 	AFFECT_DATA *pAf;
@@ -2733,21 +2703,23 @@
 	argument = one_argument(argument, mod);
 	one_argument(argument, bvector);
 
-	if (type[0] == '\0' || (typ = flag_value(apply_types, type)) == NO_FLAG)
+	if (IS_NULLSTR(type)
+		|| (typ = (where_t) flag_value(apply_types, type)) == NO_FLAG)
 	{
 		chprintln(ch, "Invalid apply type. Valid apply types are:");
 		show_help(ch, "apptype");
 		return FALSE;
 	}
 
-	if (loc[0] == '\0' || (value = flag_value(apply_flags, loc)) == NO_FLAG)
+	if (IS_NULLSTR(loc)
+		|| (value = (apply_t) flag_value(apply_flags, loc)) == NO_FLAG)
 	{
 		chprintln(ch, "Valid applys are:");
 		show_help(ch, "apply");
 		return FALSE;
 	}
 
-	if (bvector[0] == '\0' ||
+	if (IS_NULLSTR(bvector) ||
 		(bv = flag_value(bitvector_type[typ].table, bvector)) == NO_FLAG)
 	{
 		chprintln(ch, "Invalid bitvector type.");
@@ -2756,7 +2728,7 @@
 		return FALSE;
 	}
 
-	if (mod[0] == '\0' || !is_number(mod))
+	if (IS_NULLSTR(mod) || !is_number(mod))
 	{
 		chprintln(ch,
 				  "Syntax:  addapply [type] [location] [#xmod] [bitvector]");
@@ -2766,7 +2738,7 @@
 	pAf = new_affect();
 	pAf->location = value;
 	pAf->modifier = atoi(mod);
-	pAf->where = apply_types[typ].bit;
+	pAf->where = typ;
 	pAf->type = -1;
 	pAf->duration = -1;
 	pAf->bitvector = bv;
@@ -2781,19 +2753,19 @@
  * My thanks to Hans Hvidsten Birkeland and Noam Krendel(Walker)
  * for really teaching me how to manipulate pointers.
  */
-OEDIT(oedit_delaffect)
+OLCED(oedit_delaffect)
 {
 	OBJ_INDEX_DATA *pObj;
 	AFFECT_DATA *pAf;
 	char affect[MAX_STRING_LENGTH];
 	int value;
-	int cnt = 0;
+	int cnt = -1;
 
 	EDIT_OBJ(ch, pObj);
 
 	one_argument(argument, affect);
 
-	if (!is_number(affect) || affect[0] == '\0')
+	if (!is_number(affect) || IS_NULLSTR(affect))
 	{
 		chprintln(ch, "Syntax:  delaffect [#xaffect]");
 		return FALSE;
@@ -2827,7 +2799,7 @@
 bool set_value(CHAR_DATA * ch, OBJ_INDEX_DATA * pObj, const char *argument,
 			   int value)
 {
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		set_obj_values(ch, pObj, -1, "");	/* '\0' changed to "" -- Hugin */
 		return FALSE;
@@ -2856,7 +2828,7 @@
 	return FALSE;
 }
 
-OEDIT(oedit_create)
+OLCED(oedit_create)
 {
 	OBJ_INDEX_DATA *pObj;
 	AREA_DATA *pArea;
@@ -2864,7 +2836,7 @@
 	int iHash;
 
 	value = atol(argument);
-	if (argument[0] == '\0' || value == 0)
+	if (IS_NULLSTR(argument) || value == 0)
 	{
 		chprintln(ch, "Syntax:  oedit create [vnum]");
 		return FALSE;
@@ -2906,17 +2878,13 @@
 /*
  * Mobile Editor Functions.
  */
-MEDIT(medit_show)
+OLCED(medit_show)
 {
 	MOB_INDEX_DATA *pMob;
 	PROG_LIST *list;
 
 	EDIT_MOB(ch, pMob);
 
-	chprintf(ch, "%s\n\r",
-			 stringf(ch, 0, ALIGN_CENTER, "-",
-					 FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
-
 	chprintlnf(ch, "Name:        [%s]\n\rArea:        [%5d] %s",
 			   pMob->player_name, !pMob->area ? -1 : pMob->area->vnum,
 			   !pMob->area ? "No Area" : pMob->area->name);
@@ -3050,11 +3018,10 @@
 		}
 	}
 
-	chprintln(ch, draw_line(ch, NULL, 0));
 	return FALSE;
 }
 
-MEDIT(medit_create)
+OLCED(medit_create)
 {
 	MOB_INDEX_DATA *pMob;
 	AREA_DATA *pArea;
@@ -3062,7 +3029,7 @@
 	int iHash;
 
 	value = atol(argument);
-	if (argument[0] == '\0' || value == 0)
+	if (IS_NULLSTR(argument) || value == 0)
 	{
 		chprintln(ch, "Syntax:  medit create [vnum]");
 		return FALSE;
@@ -3103,7 +3070,7 @@
 	return TRUE;
 }
 
-MEDIT(medit_delete)
+OLCED(medit_delete)
 {
 	CHAR_DATA *wch, *wnext;
 	MOB_INDEX_DATA *pMob;
@@ -3258,30 +3225,54 @@
 	return TRUE;
 }
 
+OLCED(mudedit_show)
+{
+	int i;
+
+	chprintln(ch, draw_line(ch, NULL, 0));
+	chprintlnf(ch, "Pulse Per Second        : %d", mud_info.pulsepersec);
+	chprintlnf(ch, "Weather Random Factor    : %d", mud_info.rand_factor);
+	chprintlnf(ch, "Weather Climate Factor   : %d", mud_info.climate_factor);
+	chprintlnf(ch, "Weather Unit             : %d", mud_info.weath_unit);
+	chprintlnf(ch, "Weather Max Vector       : %d", mud_info.max_vector);
+
+	chprintln(ch, stringf(ch, 0, ALIGN_CENTER, "*", "[ Flag Values ]"));
+
+	for (i = 0; mud_flags[i].name != NULL; i++)
+	{
+		chprintf(ch, "%-24.24s %-10s%s", mud_flags[i].name,
+				 IS_SET(mud_info.mud_flags,
+						mud_flags[i].bit) ? "[On ]" : "[Off]",
+				 i % 2 == 0 ? "\n\r" : "  ");
+	}
+	if (i % 2 == 0)
+		chprintln(ch, "");
+	chprintln(ch, draw_line(ch, NULL, 0));
+	return TRUE;
+}
+
 void show_liqlist(CHAR_DATA * ch)
 {
 	int liq;
 	BUFFER *buffer;
-	char buf[MAX_STRING_LENGTH];
 
 	buffer = new_buf();
 
 	for (liq = 0; liq_table[liq].liq_name != NULL; liq++)
 	{
 		if ((liq % 21) == 0)
-			add_buf(buffer,
-					"Name                 Color          Proof Full Thirst Food Ssize\n\r");
+			bprintln(buffer,
+					 "Name                 Color          Proof Full Thirst Food Ssize");
 
-		sprintf(buf, "%-20s %-14s %5d %4d %6d %4d %5d\n\r",
-				liq_table[liq].liq_name, liq_table[liq].liq_color,
-				liq_table[liq].liq_affect[0],
-				liq_table[liq].liq_affect[1],
-				liq_table[liq].liq_affect[2],
-				liq_table[liq].liq_affect[3], liq_table[liq].liq_affect[4]);
-		add_buf(buffer, buf);
+		bprintlnf(buffer, "%-20s %-14s %5d %4d %6d %4d %5d",
+				  liq_table[liq].liq_name, liq_table[liq].liq_color,
+				  liq_table[liq].liq_affect[0],
+				  liq_table[liq].liq_affect[1],
+				  liq_table[liq].liq_affect[2],
+				  liq_table[liq].liq_affect[3], liq_table[liq].liq_affect[4]);
 	}
 
-	page_to_char(buf_string(buffer), ch);
+	sendpage(ch, buf_string(buffer));
 	free_buf(buffer);
 
 	return;
@@ -3291,39 +3282,36 @@
 {
 	int att;
 	BUFFER *buffer;
-	char buf[MAX_STRING_LENGTH];
 
 	buffer = new_buf();
 
 	for (att = 0; attack_table[att].name != NULL; att++)
 	{
 		if ((att % 21) == 0)
-			add_buf(buffer, "Name                 Noun\n\r");
+			bprintln(buffer, "Name                 Noun");
 
-		sprintf(buf, "%-20s %-20s\n\r", attack_table[att].name,
-				attack_table[att].noun);
-		add_buf(buffer, buf);
+		bprintlnf(buffer, "%-20s %-20s", attack_table[att].name,
+				  attack_table[att].noun);
 	}
 
-	page_to_char(buf_string(buffer), ch);
+	sendpage(ch, buf_string(buffer));
 	free_buf(buffer);
 
 	return;
 }
 
-MEDIT(medit_group)
+OLCED(medit_group)
 {
 	MOB_INDEX_DATA *pMob;
 	MOB_INDEX_DATA *pMTemp;
 	char arg[MAX_STRING_LENGTH];
-	char buf[MAX_STRING_LENGTH];
 	int temp;
 	BUFFER *buffer;
 	bool found = FALSE;
 
 	EDIT_MOB(ch, pMob);
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch, "Syntax: group [number]");
 		chprintln(ch, "        group show [number]");
@@ -3355,14 +3343,13 @@
 			if (pMTemp && (pMTemp->group == atol(argument)))
 			{
 				found = TRUE;
-				sprintf(buf, "[%5ld] %s\n\r", pMTemp->vnum,
-						pMTemp->player_name);
-				add_buf(buffer, buf);
+				bprintlnf(buffer, "[%5ld] %s", pMTemp->vnum,
+						  pMTemp->player_name);
 			}
 		}
 
 		if (found)
-			page_to_char(buf_string(buffer), ch);
+			sendpage(ch, buf_string(buffer));
 		else
 			chprintln(ch, "No mobs in that group.");
 
@@ -3373,439 +3360,154 @@
 	return FALSE;
 }
 
-MEDIT(medit_addmprog)
+VALIDATE_FUN(validate_level)
 {
-	flag_t value;
-	MOB_INDEX_DATA *pMob;
-	PROG_LIST *list;
-	PROG_CODE *code;
-	char trigger[MAX_STRING_LENGTH];
-	char phrase[MAX_STRING_LENGTH];
-	char num[MAX_STRING_LENGTH];
-
-	EDIT_MOB(ch, pMob);
-	argument = one_argument(argument, num);
-	argument = one_argument(argument, trigger);
-	argument = one_argument(argument, phrase);
-
-	if (!is_number(num) || trigger[0] == '\0' || phrase[0] == '\0')
-	{
-		chprintln(ch, "Syntax:   addmprog [vnum] [trigger] [phrase]");
-		return FALSE;
-	}
-
-	if ((value = flag_value(mprog_flags, trigger)) == NO_FLAG)
-	{
-		chprintln(ch, "Valid flags are:");
-		show_help(ch, "mprog");
-		return FALSE;
-	}
+	int num = *(int *) arg;
 
-	if ((code = get_prog_index(atol(num), PRG_MPROG)) == NULL)
+	if (num < 0 || num > MAX_LEVEL)
 	{
-		chprintln(ch, "No such MOBProgram.");
+		chprintf(ch, "Number must be between 0 and %d.\n\r", MAX_LEVEL);
 		return FALSE;
 	}
 
-	list = new_prog();
-	list->vnum = atol(num);
-	list->trig_type = value;
-	list->trig_phrase = str_dup(phrase);
-	replace_string(list->code, code->code);
-	SET_BIT(pMob->mprog_flags, value);
-	LINK(list, pMob->first_mprog, pMob->last_mprog, next, prev);
-
-	chprintln(ch, "Mprog Added.");
 	return TRUE;
 }
 
-MEDIT(medit_delmprog)
+VALIDATE_FUN(validate_align)
 {
-	MOB_INDEX_DATA *pMob;
-	PROG_LIST *list;
-	char mprog[MAX_STRING_LENGTH];
-	int value;
-	int cnt = 0;
-
-	EDIT_MOB(ch, pMob);
+	int num = *(int *) arg;
 
-	one_argument(argument, mprog);
-	if (!is_number(mprog) || mprog[0] == '\0')
+	if (num < -1000 || num > 1000)
 	{
-		chprintln(ch, "Syntax:  delmprog [#mprog]");
+		chprintln(ch, "Number must be between -1000 and 1000.");
 		return FALSE;
 	}
 
-	value = atoi(mprog);
+	return TRUE;
+}
 
-	if (value < 0)
+ED_FUN_DEC(olced_str)
+{
+	const char **string = (const char **) arg;
+	char buf[MSL];
+
+	if (IS_NULLSTR(argument))
 	{
-		chprintln(ch, "Only non-negative mprog-numbers allowed.");
+		chprintf(ch, "Syntax: %s string\n\r", n_fun);
 		return FALSE;
 	}
 
-	for (list = pMob->first_mprog; list != NULL; list = list->next)
-		if ((++cnt == value))
-			break;
-
-	if (!list)
-	{
-		chprintln(ch, "MEdit:  Non existant mprog.");
+	if (validator && !validator(ch, argument))
 		return FALSE;
-	}
-	REMOVE_BIT(pMob->mprog_flags, list->trig_type);
-	UNLINK(list, pMob->first_mprog, pMob->last_mprog, next, prev);
-	free_prog(list);
 
-	chprintln(ch, "Mprog removed.");
+	sprintf(buf, "%s%s", argument, par == NULL ? "" : "\n\r");
+	replace_string(*string, buf);
+	chprintln(ch, "Ok.");
 	return TRUE;
 }
 
-OEDIT(oedit_addoprog)
+ED_FUN_DEC(olced_desc)
 {
-	flag_t value;
-	OBJ_INDEX_DATA *pObj;
-	PROG_LIST *list;
-	PROG_CODE *code;
-	char trigger[MSL];
-	char phrase[MSL];
-	char num[MSL];
-
-	EDIT_OBJ(ch, pObj);
-	argument = one_argument(argument, num);
-	argument = one_argument(argument, trigger);
-	strcpy(phrase, argument);
-
-	if (!is_number(num) || IS_NULLSTR(trigger) || IS_NULLSTR(phrase))
+	if (IS_NULLSTR(argument))
 	{
-		chprintln(ch, "Syntax:   addoprog [vnum] [trigger] [phrase]");
-		return FALSE;
+		string_append(ch, (const char **) arg);
+		return TRUE;
 	}
 
-	if ((value = flag_value(oprog_flags, trigger)) == NO_FLAG)
+	chprintln(ch, "Syntax : desc");
+
+	return FALSE;
+}
+
+ED_FUN_DEC(olced_bool)
+{
+	if (IS_NULLSTR(argument))
 	{
-		chprintln(ch, "Valid flags are:");
-		show_help(ch, "oprog");
+		chprintf(ch, "Syntax : %s [TRUE/FALSE]\n\r\n\r", n_fun);
 		return FALSE;
 	}
 
-	if ((code = get_prog_index(atol(num), PRG_OPROG)) == NULL)
+	if (!str_cmp(argument, "TRUE"))
+		*(bool *) arg = TRUE;
+	else if (!str_cmp(argument, "FALSE"))
+		*(bool *) arg = FALSE;
+	else
 	{
-		chprintln(ch, "No such OBJProgram.");
+		chprintln(ch, "ERROR : invalid argument.");
 		return FALSE;
 	}
 
-	list = new_prog();
-	list->vnum = atol(num);
-	list->trig_type = value;
-	replace_string(list->trig_phrase, phrase);
-	replace_string(list->code, code->code);
-	SET_BIT(pObj->oprog_flags, value);
-	LINK(list, pObj->first_oprog, pObj->last_oprog, next, prev);
-	chprintln(ch, "Oprog Added.");
+	chprintln(ch, "Ok.");
 	return TRUE;
 }
 
-OEDIT(oedit_deloprog)
+ED_FUN_DEC(olced_olded)
 {
-	OBJ_INDEX_DATA *pObj;
-	PROG_LIST *list;
-	char oprog[MSL];
-	int value;
-	int cnt = -1;
+	return (*(OLC_FUN *) par) (ch, argument);
+}
 
-	EDIT_OBJ(ch, pObj);
+ED_FUN_DEC(olced_number)
+{
+	int *value = (int *) arg;
+	char *endptr;
+	int temp;
+	char arg1[MIL];
 
-	one_argument(argument, oprog);
-	if (!is_number(oprog) || IS_NULLSTR(oprog))
+	one_argument(argument, arg1);
+	temp = strtol(arg1, &endptr, 0);
+	if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
 	{
-		chprintln(ch, "Syntax:  deloprog [#oprog]");
+		chprintf(ch, "Syntax: %s number\n\r", n_fun);
 		return FALSE;
 	}
 
-	value = atoi(oprog);
-
-	if (value < 0)
-	{
-		chprintln(ch, "Only non-negative oprog-numbers allowed.");
+	if (validator && !validator(ch, &temp))
 		return FALSE;
-	}
 
-	for (list = pObj->first_oprog; list != NULL; list = list->next)
-		if (++cnt == value)
-			break;
+	*value = temp;
+	chprintln(ch, "Ok.");
+	return TRUE;
+}
 
-	if (!list)
+ED_FUN_DEC(olced_number_long)
+{
+	long *value = (long *) arg;
+	char *endptr;
+	long temp;
+	char arg1[MIL];
+
+	one_argument(argument, arg1);
+	temp = strtol(arg1, &endptr, 0);
+	if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
 	{
-		chprintln(ch, "OEdit:  Non existant oprog.");
+		chprintf(ch, "Syntax: %s number\n\r", n_fun);
 		return FALSE;
 	}
 
-	REMOVE_BIT(pObj->oprog_flags, list->trig_type);
-	UNLINK(list, pObj->first_oprog, pObj->last_oprog, next, prev);
-	free_prog(list);
+	if (validator && !validator(ch, &temp))
+		return FALSE;
 
-	chprintln(ch, "Oprog removed.");
+	*value = temp;
+	chprintln(ch, "Ok.");
 	return TRUE;
 }
 
-REDIT(redit_addrprog)
+ED_FUN_DEC(olced_vnum)
 {
-	flag_t value;
-	ROOM_INDEX_DATA *pRoom;
-	PROG_LIST *list;
-	PROG_CODE *code;
-	char trigger[MSL];
-	char phrase[MSL];
-	char num[MSL];
-
-	EDIT_ROOM(ch, pRoom);
-	argument = one_argument(argument, num);
-	argument = one_argument(argument, trigger);
-	strcpy(phrase, argument);
-
-	if (!is_number(num) || IS_NULLSTR(trigger) || IS_NULLSTR(phrase))
-	{
-		chprintln(ch, "Syntax:   addrprog [vnum] [trigger] [phrase]");
-		return FALSE;
-	}
+	vnum_t *value = (vnum_t *) arg;
+	char *endptr;
+	vnum_t temp;
+	char arg1[MIL];
 
-	if ((value = flag_value(rprog_flags, trigger)) == NO_FLAG)
+	one_argument(argument, arg1);
+	temp = strtol(arg1, &endptr, 0);
+	if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
 	{
-		chprintln(ch, "Valid flags are:");
-		show_help(ch, "rprog");
+		chprintf(ch, "Syntax: %s number\n\r", n_fun);
 		return FALSE;
 	}
 
-	if ((code = get_prog_index(atol(num), PRG_RPROG)) == NULL)
-	{
-		chprintln(ch, "No such ROOMProgram.");
-		return FALSE;
-	}
-
-	list = new_prog();
-	list->vnum = atol(num);
-	list->trig_type = value;
-	replace_string(list->trig_phrase, phrase);
-	replace_string(list->code, code->code);
-	SET_BIT(pRoom->rprog_flags, value);
-	LINK(list, pRoom->first_rprog, pRoom->last_rprog, next, prev);
-	chprintln(ch, "Rprog Added.");
-	return TRUE;
-}
-
-REDIT(redit_delrprog)
-{
-	ROOM_INDEX_DATA *pRoom;
-	PROG_LIST *list;
-	char rprog[MSL];
-	int value;
-	int cnt = -1;
-
-	EDIT_ROOM(ch, pRoom);
-
-	one_argument(argument, rprog);
-	if (!is_number(rprog) || IS_NULLSTR(rprog))
-	{
-		chprintln(ch, "Syntax:  delrprog [#rprog]");
-		return FALSE;
-	}
-
-	value = atoi(rprog);
-
-	if (value < 0)
-	{
-		chprintln(ch, "Only non-negative rprog-numbers allowed.");
-		return FALSE;
-	}
-
-	for (list = pRoom->first_rprog; list != NULL; list = list->next)
-		if ((++cnt == value))
-			break;
-
-	if (!list)
-	{
-		chprintln(ch, "REdit:  Non existant rprog.");
-		return FALSE;
-	}
-	REMOVE_BIT(pRoom->rprog_flags, list->trig_type);
-	UNLINK(list, pRoom->first_rprog, pRoom->last_rprog, next, prev);
-	free_prog(list);
-	chprintln(ch, "Rprog removed.");
-	return TRUE;
-}
-
-VALIDATE_FUN(validate_level)
-{
-	int num = *(int *) arg;
-
-	if (num < 0 || num > MAX_LEVEL)
-	{
-		chprintf(ch, "Number must be between 0 and %d.\n\r", MAX_LEVEL);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-VALIDATE_FUN(validate_align)
-{
-	int num = *(int *) arg;
-
-	if (num < -1000 || num > 1000)
-	{
-		chprintln(ch, "Number must be between -1000 and 1000.");
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-ED_FUN_DEC(olced_str)
-{
-	VALIDATE_FUN *validator;
-	const char **string = (const char **) arg;
-
-	if (IS_NULLSTR(argument))
-	{
-		chprintf(ch, "Syntax: %s string\n\r", n_fun);
-		return FALSE;
-	}
-
-	if ((validator = (VALIDATE_FUN *) par) && !validator(ch, argument))
-		return FALSE;
-
-	replace_string(*string, argument);
-	chprintln(ch, "Ok.");
-	return TRUE;
-}
-
-ED_FUN_DEC(olced_str_line)
-{
-	VALIDATE_FUN *validator;
-	const char **string = (const char **) arg;
-	char buf[MSL];
-
-	if (IS_NULLSTR(argument))
-	{
-		chprintf(ch, "Syntax: %s string\n\r", n_fun);
-		return FALSE;
-	}
-
-	if ((validator = (VALIDATE_FUN *) par) && !validator(ch, argument))
-		return FALSE;
-
-	sprintf(buf, "%s\n\r", argument);
-	replace_string(*string, buf);
-	chprintln(ch, "Ok.");
-	return TRUE;
-}
-
-ED_FUN_DEC(olced_desc)
-{
-	if (IS_NULLSTR(argument))
-	{
-		string_append(ch, (const char **) arg);
-		return TRUE;
-	}
-
-	chprintln(ch, "Syntax : desc");
-
-	return FALSE;
-}
-
-ED_FUN_DEC(olced_bool)
-{
-	if (IS_NULLSTR(argument))
-	{
-		chprintf(ch, "Syntax : %s [TRUE/FALSE]\n\r\n\r", n_fun);
-		return FALSE;
-	}
-
-	if (!str_cmp(argument, "TRUE"))
-		*(bool *) arg = TRUE;
-	else if (!str_cmp(argument, "FALSE"))
-		*(bool *) arg = FALSE;
-	else
-	{
-		chprintln(ch, "ERROR : invalid argument.");
-		return FALSE;
-	}
-
-	chprintln(ch, "Ok.");
-	return TRUE;
-}
-
-ED_FUN_DEC(olced_olded)
-{
-	return (*(OLC_FUN *) par) (ch, argument);
-}
-
-ED_FUN_DEC(olced_number)
-{
-	int *value = (int *) arg;
-	char *endptr;
-	int temp;
-	char arg1[MIL];
-	VALIDATE_FUN *validator;
-
-	one_argument(argument, arg1);
-	temp = strtol(arg1, &endptr, 0);
-	if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
-	{
-		chprintf(ch, "Syntax: %s number\n\r", n_fun);
-		return FALSE;
-	}
-
-	if ((validator = (VALIDATE_FUN *) par) && !validator(ch, &temp))
-		return FALSE;
-
-	*value = temp;
-	chprintln(ch, "Ok.");
-	return TRUE;
-}
-
-ED_FUN_DEC(olced_number_long)
-{
-	long *value = (long *) arg;
-	char *endptr;
-	long temp;
-	char arg1[MIL];
-	VALIDATE_FUN *validator;
-
-	one_argument(argument, arg1);
-	temp = strtol(arg1, &endptr, 0);
-	if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
-	{
-		chprintf(ch, "Syntax: %s number\n\r", n_fun);
-		return FALSE;
-	}
-
-	if ((validator = (VALIDATE_FUN *) par) && !validator(ch, &temp))
-		return FALSE;
-
-	*value = temp;
-	chprintln(ch, "Ok.");
-	return TRUE;
-}
-
-ED_FUN_DEC(olced_vnum)
-{
-	vnum_t *value = (vnum_t *) arg;
-	char *endptr;
-	vnum_t temp;
-	char arg1[MIL];
-	VALIDATE_FUN *validator;
-
-	one_argument(argument, arg1);
-	temp = strtol(arg1, &endptr, 0);
-	if (IS_NULLSTR(arg1) || !IS_NULLSTR(endptr))
-	{
-		chprintf(ch, "Syntax: %s number\n\r", n_fun);
-		return FALSE;
-	}
-
-	if ((validator = (VALIDATE_FUN *) par) && !validator(ch, &temp))
+	if (validator && !validator(ch, &temp))
 		return FALSE;
 
 	*value = temp;
@@ -3816,7 +3518,6 @@
 void show_flags_buf(BUFFER * output, const struct flag_type *flag_table)
 {
 	int flag;
-	char buf[MSL];
 	int col;
 
 	col = 0;
@@ -3824,15 +3525,14 @@
 	{
 		if (flag_table[flag].settable)
 		{
-			sprintf(buf, "%-19.18s", flag_table[flag].name);
-			add_buf(output, buf);
+			bprintf(output, "%-19.18s", flag_table[flag].name);
 			if (++col % 4 == 0)
-				add_buf(output, "\n\r");
+				bprintln(output, "");
 		}
 	}
 
 	if (col % 4 != 0)
-		add_buf(output, "\n\r");
+		bprintln(output, "");
 }
 
 /*****************************************************************************
@@ -3845,7 +3545,7 @@
 
 	output = new_buf();
 	show_flags_buf(output, flag_table);
-	page_to_char(buf_string(output), ch);
+	sendpage(ch, buf_string(output));
 	free_buf(output);
 }
 
@@ -3892,6 +3592,8 @@
 					 n_fun, f->name);
 			return FALSE;
 		}
+		if (validator && !validator(ch, &f->bit))
+			return FALSE;
 		*(int *) arg = f->bit;
 		chprintf(ch, "%s: '%s': Ok.\n\n\r", n_fun, f->name);
 		return TRUE;
@@ -3928,6 +3630,8 @@
 
 	if (marked)
 	{
+		if (validator && !validator(ch, &marked))
+			return FALSE;
 		TOGGLE_BIT(*(flag_t *) arg, marked);
 		chprintf(ch, "%s: '%s': flag(s) toggled.\n\r",
 				 n_fun, flag_string((const struct flag_type *) par, marked));
@@ -4069,7 +3773,7 @@
 		return TRUE;
 	}
 
-	olced_shop(n_fun, ch, str_empty, arg, par);
+	olced_shop(n_fun, ch, str_empty, arg, par, validator);
 
 	return FALSE;
 }
@@ -4077,6 +3781,7 @@
 ED_FUN_DEC(olced_spec)
 {
 	SPEC_FUN **spec = (SPEC_FUN **) arg;
+	SPEC_FUN *fun;
 
 	if (IS_NULLSTR(argument))
 	{
@@ -4091,9 +3796,13 @@
 		return TRUE;
 	}
 
-	if (spec_lookup(argument))
+	fun = spec_lookup(argument);
+
+	if (fun)
 	{
-		*spec = spec_lookup(argument);
+		if (validator && !validator(ch, &fun))
+			return FALSE;
+		*spec = fun;
 		chprintln(ch, "Spec set.");
 		return TRUE;
 	}
@@ -4266,9 +3975,9 @@
 
 ED_FUN_DEC(olced_ed)
 {
-	EXTRA_DESCR_DATA *ed;
-	EXTRA_DESCR_DATA **pEd = (EXTRA_DESCR_DATA **) arg;
-	EXTRA_DESCR_DATA **lEd = (EXTRA_DESCR_DATA **) par;
+	EXTRA_DESCR_DATA *ed, *ed_first, *ed_last;
+	OBJ_INDEX_DATA *pObj;
+	ROOM_INDEX_DATA *pRoom;
 	char command[MAX_INPUT_LENGTH];
 	char keyword[MAX_INPUT_LENGTH];
 
@@ -4277,11 +3986,29 @@
 
 	if (IS_NULLSTR(command))
 	{
-		chprintln(ch, "Syntax:  ed add [keyword]");
-		chprintln(ch, "         ed delete [keyword]");
-		chprintln(ch, "         ed edit [keyword]");
-		chprintln(ch, "         ed format [keyword]");
-		chprintln(ch, "         ed rename [keyword]");
+		chprintlnf(ch, "Syntax:  %s add [keyword]", n_fun);
+		chprintlnf(ch, "         %s delete [keyword]", n_fun);
+		chprintlnf(ch, "         %s edit [keyword]", n_fun);
+		chprintlnf(ch, "         %s format [keyword]", n_fun);
+		chprintlnf(ch, "         %s rename [keyword]", n_fun);
+		return FALSE;
+	}
+
+	switch (ch->desc->editor)
+	{
+	case ED_OBJECT:
+		EDIT_OBJ(ch, pObj);
+		ed_first = pObj->first_extra_descr;
+		ed_last = pObj->last_extra_descr;
+		break;
+	case ED_ROOM:
+		EDIT_ROOM(ch, pRoom);
+		ed_first = pRoom->first_extra_descr;
+		ed_last = pRoom->last_extra_descr;
+		break;
+
+	default:
+		chprintln(ch, "ERROR: bad editor.");
 		return FALSE;
 	}
 
@@ -4289,14 +4016,13 @@
 	{
 		if (IS_NULLSTR(keyword))
 		{
-			chprintln(ch, "Syntax:  ed add [keyword]");
+			chprintlnf(ch, "Syntax: %s add [keyword]", n_fun);
 			return FALSE;
 		}
 
 		ed = new_extra_descr();
 		replace_string(ed->keyword, keyword);
-		LINK(ed, *pEd, *lEd, next, prev);
-
+		LINK(ed, ed_first, ed_last, next, prev);
 		string_append(ch, &ed->description);
 
 		return TRUE;
@@ -4306,11 +4032,11 @@
 	{
 		if (IS_NULLSTR(keyword))
 		{
-			chprintln(ch, "Syntax:  ed edit [keyword]");
+			chprintlnf(ch, "Syntax: %s edit [keyword]", n_fun);
 			return FALSE;
 		}
 
-		for (ed = *pEd; ed; ed = ed->next)
+		for (ed = ed_first; ed; ed = ed->next)
 		{
 			if (is_name(keyword, ed->keyword))
 				break;
@@ -4329,19 +4055,16 @@
 
 	if (!str_cmp(command, "delete"))
 	{
-		EXTRA_DESCR_DATA *ped = NULL;
-
 		if (IS_NULLSTR(keyword))
 		{
-			chprintln(ch, "Syntax:  ed delete [keyword]");
+			chprintlnf(ch, "Syntax: %s delete [keyword]", n_fun);
 			return FALSE;
 		}
 
-		for (ed = *pEd; ed; ed = ed->next)
+		for (ed = ed_first; ed; ed = ed->next)
 		{
 			if (is_name(keyword, ed->keyword))
 				break;
-			ped = ed;
 		}
 
 		if (!ed)
@@ -4350,7 +4073,7 @@
 			return FALSE;
 		}
 
-		UNLINK(ed, *pEd, *lEd, next, prev);
+		UNLINK(ed, ed_first, ed_last, next, prev);
 
 		free_extra_descr(ed);
 
@@ -4360,19 +4083,16 @@
 
 	if (!str_cmp(command, "format"))
 	{
-		EXTRA_DESCR_DATA *ped = NULL;
-
 		if (IS_NULLSTR(keyword))
 		{
-			chprintln(ch, "Syntax:  ed format [keyword]");
+			chprintlnf(ch, "Syntax: %s format [keyword]", n_fun);
 			return FALSE;
 		}
 
-		for (ed = *pEd; ed; ed = ed->next)
+		for (ed = ed_first; ed; ed = ed->next)
 		{
 			if (is_name(keyword, ed->keyword))
 				break;
-			ped = ed;
 		}
 
 		if (!ed)
@@ -4389,19 +4109,16 @@
 
 	if (!str_cmp(command, "rename"))
 	{
-		EXTRA_DESCR_DATA *ped = NULL;
-
 		if (IS_NULLSTR(keyword))
 		{
-			chprintln(ch, "Syntax:  ed rename [old] [new]");
+			chprintlnf(ch, "Syntax: %s rename [old] [new]", n_fun);
 			return FALSE;
 		}
 
-		for (ed = *pEd; ed; ed = ed->next)
+		for (ed = ed_first; ed; ed = ed->next)
 		{
 			if (is_name(keyword, ed->keyword))
 				break;
-			ped = ed;
 		}
 
 		if (!ed)
@@ -4416,7 +4133,7 @@
 		return TRUE;
 	}
 
-	return olced_ed(n_fun, ch, "", arg, par);
+	return olced_ed(n_fun, ch, "", arg, par, validator);
 }
 
 ED_FUN_DEC(olced_direction)
@@ -4472,7 +4189,7 @@
 	return templookup(n_fun, ch, argument, arg, par, -1);
 }
 
-CEDIT(cedit_show)
+OLCED(cedit_show)
 {
 	CLAN_DATA *pClan;
 	int r;
@@ -4488,7 +4205,7 @@
 	return TRUE;
 }
 
-CEDIT(cedit_rank)
+OLCED(cedit_rank)
 {
 	CLAN_DATA *pClan;
 	char arg1[MIL];
@@ -4516,7 +4233,7 @@
 	return FALSE;
 }
 
-CEDIT(cedit_create)
+OLCED(cedit_create)
 {
 	CLAN_DATA *pClan;
 	char buf[MIL];
@@ -4536,7 +4253,7 @@
 	return TRUE;
 }
 
-CEDIT(cedit_delete)
+OLCED(cedit_delete)
 {
 	CLAN_DATA *pClan;
 
@@ -4598,7 +4315,7 @@
 	return TRUE;
 }
 
-OEDIT(oedit_autoweapon)
+OLCED(oedit_autoweapon)
 {
 	OBJ_INDEX_DATA *pObj;
 
@@ -4631,7 +4348,7 @@
 	return TRUE;
 }
 
-OEDIT(oedit_autoarmor)
+OLCED(oedit_autoarmor)
 {
 	OBJ_INDEX_DATA *pObj;
 
@@ -4663,7 +4380,7 @@
 	return TRUE;
 }
 
-MEDIT(medit_autoset)
+OLCED(medit_autoset)
 {
 	MOB_INDEX_DATA *pMob;
 
@@ -4680,7 +4397,7 @@
 	return TRUE;
 }
 
-MEDIT(medit_autohard)
+OLCED(medit_autohard)
 {
 	MOB_INDEX_DATA *pMob;
 
@@ -4699,7 +4416,7 @@
 	return TRUE;
 }
 
-MEDIT(medit_autoeasy)
+OLCED(medit_autoeasy)
 {
 	MOB_INDEX_DATA *pMob;
 
@@ -4713,5 +4430,563 @@
 
 	chprintln(ch, " Easy values set, check for accuracy.");
 
+	return TRUE;
+}
+
+void reset_pflags(flag_t * pflag, PROG_LIST * pl)
+{
+	flag_t bitv = 0;
+
+	for (; pl; pl = pl->next)
+		SET_BIT(bitv, pl->trig_type);
+
+	*pflag = bitv;
+}
+
+ED_FUN_DEC(olced_addprog)
+{
+	flag_t value, *flags;
+	const struct flag_type *flagtable;
+	PROG_LIST *list;
+	PROG_LIST **progs_first;
+	PROG_LIST **progs_last;
+	PROG_CODE *code;
+	MOB_INDEX_DATA *pMob;
+	OBJ_INDEX_DATA *pObj;
+	ROOM_INDEX_DATA *pRoom;
+	char trigger[MSL];
+	char phrase[MSL];
+	char num[MSL];
+	prog_t type;
+
+	argument = one_argument(argument, num);
+	argument = one_argument(argument, trigger);
+	strcpy(phrase, argument);
+
+	if (!is_number(num) || IS_NULLSTR(trigger) || IS_NULLSTR(phrase))
+	{
+		chprintlnf(ch, "Syntax: %s [vnum] [trigger] [phrase]", n_fun);
+		return FALSE;
+	}
+
+	switch (ch->desc->editor)
+	{
+	case ED_MOBILE:
+		flagtable = mprog_flags;
+		type = PRG_MPROG;
+		EDIT_MOB(ch, pMob);
+		progs_first = &pMob->first_mprog;
+		progs_last = &pMob->last_mprog;
+		flags = &pMob->mprog_flags;
+		break;
+	case ED_OBJECT:
+		flagtable = oprog_flags;
+		type = PRG_OPROG;
+		EDIT_OBJ(ch, pObj);
+		progs_first = &pObj->first_oprog;
+		progs_last = &pObj->last_oprog;
+		flags = &pObj->oprog_flags;
+		break;
+	case ED_ROOM:
+		flagtable = rprog_flags;
+		type = PRG_RPROG;
+		EDIT_ROOM(ch, pRoom);
+		progs_first = &pRoom->first_rprog;
+		progs_last = &pRoom->last_rprog;
+		flags = &pRoom->rprog_flags;
+		break;
+	default:
+		chprintln(ch, "ERROR : invalid editor.");
+		return FALSE;
+	}
+
+	if ((value = flag_value(flagtable, trigger)) == NO_FLAG)
+	{
+		chprintln(ch, "Valid flags are:");
+		show_help(ch, "ptriggers");
+		return FALSE;
+	}
+
+	if ((code = get_prog_index(atol(num), type)) == NULL)
+	{
+		chprintln(ch, "No such Program.");
+		return FALSE;
+	}
+
+	list = new_prog();
+	list->vnum = atol(num);
+	list->trig_type = value;
+	replace_string(list->trig_phrase, phrase);
+	replace_string(list->code, code->code);
+	LINK(list, *progs_first, *progs_last, next, prev);
+
+	reset_pflags(flags, *progs_first);
+
+	chprintlnf(ch, "%s: program added.", n_fun);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_delprog)
+{
+	PROG_LIST *list;
+	flag_t *flags;
+	PROG_LIST **progs_first;
+	PROG_LIST **progs_last;
+	MOB_INDEX_DATA *pMob;
+	OBJ_INDEX_DATA *pObj;
+	ROOM_INDEX_DATA *pRoom;
+	char prog[MAX_STRING_LENGTH];
+	int value;
+	int cnt = -1;
+
+	one_argument(argument, prog);
+
+	if (!is_number(prog) || IS_NULLSTR(prog))
+	{
+		chprintlnf(ch, "Syntax: %s [#prog]", n_fun);
+		return FALSE;
+	}
+
+	value = atoi(prog);
+
+	if (value < 0)
+	{
+		chprintln(ch, "Only non-negative prog-numbers allowed.");
+		return FALSE;
+	}
+
+	switch (ch->desc->editor)
+	{
+	case ED_MOBILE:
+		EDIT_MOB(ch, pMob);
+		progs_first = &pMob->first_mprog;
+		progs_last = &pMob->last_mprog;
+		flags = &pMob->mprog_flags;
+		break;
+	case ED_OBJECT:
+		EDIT_OBJ(ch, pObj);
+		progs_first = &pObj->first_oprog;
+		progs_last = &pObj->last_oprog;
+		flags = &pObj->oprog_flags;
+		break;
+	case ED_ROOM:
+		EDIT_ROOM(ch, pRoom);
+		progs_first = &pRoom->first_rprog;
+		progs_last = &pRoom->last_rprog;
+		flags = &pRoom->rprog_flags;
+		break;
+	default:
+		chprintln(ch, "ERROR : invalid editor.");
+		return FALSE;
+	}
+
+	for (list = *progs_first; list != NULL; list = list->next)
+		if (++cnt == value)
+			break;
+
+	if (!list)
+	{
+		chprintlnf(ch, "%s:  Non existant program.", n_fun);
+		return FALSE;
+	}
+
+	UNLINK(list, *progs_first, *progs_last, next, prev);
+	free_prog(list);
+
+	reset_pflags(flags, *progs_first);
+
+	chprintlnf(ch, "%s: program removed.", n_fun);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_array)
+{
+	int **value = (int **) arg;
+	int max = (int) par;
+	int temp, pos;
+	char arg1[MIL], arg2[MIL];
+
+	argument = one_argument(argument, arg1);
+	one_argument(argument, arg2);
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || !is_number(arg1)
+		|| !is_number(arg2))
+	{
+		chprintlnf(ch, "Syntax: %s <1-%d> <value>", n_fun, max);
+		return FALSE;
+	}
+
+	pos = atoi(arg1);
+	if (pos < 1 || pos > max)
+	{
+		chprintlnf(ch, "%s: invalid slot.", n_fun);
+		return FALSE;
+	}
+
+	temp = atoi(arg2);
+
+	if (validator && !validator(ch, &temp))
+		return FALSE;
+
+	(*value)[pos - 1] = temp;
+	chprintlnf(ch, "%s: slot %d = '%d': Ok.", n_fun, pos, temp);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_larray)
+{
+	long **value = (long **) arg;
+	int max = (int) par;
+	int pos;
+	long temp;
+	char arg1[MIL], arg2[MIL];
+
+	argument = one_argument(argument, arg1);
+	one_argument(argument, arg2);
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || !is_number(arg1)
+		|| !is_number(arg2))
+	{
+		chprintlnf(ch, "Syntax: %s <1-%d> <value>", n_fun, max);
+		return FALSE;
+	}
+
+	pos = atoi(arg1);
+	if (pos < 1 || pos > max)
+	{
+		chprintlnf(ch, "%s: invalid slot.", n_fun);
+		return FALSE;
+	}
+
+	temp = atol(arg2);
+
+	if (validator && !validator(ch, &temp))
+		return FALSE;
+
+	(*value)[pos - 1] = temp;
+	chprintlnf(ch, "%s: slot %d = '%ld': Ok.", n_fun, pos, temp);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_sarray)
+{
+	const char ***value = (const char ***) arg;
+	int max = (int) par;
+	int pos;
+	char arg1[MIL];
+
+	argument = one_argument(argument, arg1);
+
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(argument) || !is_number(arg1))
+	{
+		chprintlnf(ch, "Syntax: %s <1-%d> <string>", n_fun, max);
+		return FALSE;
+	}
+
+	pos = atoi(arg1);
+	if (pos < 1 || pos > max)
+	{
+		chprintlnf(ch, "%s: invalid slot.", n_fun);
+		return FALSE;
+	}
+
+	if (validator && !validator(ch, &argument))
+		return FALSE;
+
+	replace_string((*value)[pos - 1], argument);
+	chprintlnf(ch, "%s: slot %d = '%s': Ok.", n_fun, pos, argument);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_farray)
+{
+	flag_t **value = (flag_t **) arg;
+	int max = (int) par;
+	int pos;
+	flag_t temp;
+	int f;
+	const struct flag_type *table;
+	char arg1[MIL], arg2[MIL];
+
+	argument = one_argument(argument, arg1);
+	argument = one_argument(argument, arg2);
+
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || IS_NULLSTR(argument)
+		|| !is_number(arg1))
+	{
+		chprintlnf(ch, "Syntax: %s <1-%d> <flags> <string>", n_fun, max);
+		return FALSE;
+	}
+
+	pos = atoi(arg1);
+	if (pos < 1 || pos > max)
+	{
+		chprintlnf(ch, "%s: invalid slot.", n_fun);
+		return FALSE;
+	}
+
+	table = NULL;
+	for (f = 0; flag_stat_table[f].name != NULL; f++)
+	{
+		if (UPPER(flag_stat_table[f].name[0]) == UPPER(arg2[0])
+			&& !str_prefix(arg2, flag_stat_table[f].name))
+		{
+			table = flag_stat_table[f].structure;
+			break;
+		}
+	}
+	if (!table)
+	{
+		chprintlnf(ch, "%s: unknown flags", n_fun);
+		return FALSE;
+	}
+
+	if ((temp = flag_value(table, argument)) == NO_FLAG)
+	{
+		chprintln(ch, "No such flag.");
+		return FALSE;
+	}
+
+	if (validator && !validator(ch, &temp))
+		return FALSE;
+
+	(*value)[pos - 1] = temp;
+	chprintlnf(ch, "%s: slot %d = '%s': Ok.", n_fun, pos, argument);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_mclass)
+{
+	int **value = (int **) arg;
+	int max = (int) par;
+	int pos, temp;
+	char arg1[MIL], arg2[MIL];
+
+	argument = one_argument(argument, arg1);
+	one_argument(argument, arg2);
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || !is_number(arg1))
+	{
+		chprintlnf(ch, "Syntax: %s <1-%d> <class>", n_fun, max);
+		return FALSE;
+	}
+
+	pos = atoi(arg1);
+	if (pos < 1 || pos > max)
+	{
+		chprintlnf(ch, "%s: invalid slot.", n_fun);
+		return FALSE;
+	}
+
+	if ((temp = class_lookup(arg2)) == -1)
+	{
+		chprintlnf(ch, "%s: no such class.", n_fun);
+		return FALSE;
+	}
+
+	if (validator && !validator(ch, &temp))
+		return FALSE;
+
+	(*value)[pos - 1] = temp;
+	chprintlnf(ch, "%s: slot %d = '%s': Ok.", n_fun, pos, arg2);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_stance)
+{
+	int **value = (int **) arg;
+	int pos, temp;
+	char arg1[MIL], arg2[MIL];
+
+	argument = one_argument(argument, arg1);
+	one_argument(argument, arg2);
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
+	{
+		chprintlnf(ch, "Syntax: %s <stance> <value>", n_fun);
+		return FALSE;
+	}
+
+	if (!str_cmp(arg1, "viper"))
+		pos = STANCE_VIPER;
+	else if (!str_cmp(arg1, "crane"))
+		pos = STANCE_CRANE;
+	else if (!str_cmp(arg1, "crab"))
+		pos = STANCE_CRAB;
+	else if (!str_cmp(arg1, "mongoose"))
+		pos = STANCE_MONGOOSE;
+	else if (!str_cmp(arg1, "bull"))
+		pos = STANCE_BULL;
+	else if (!str_cmp(arg1, "mantis"))
+		pos = STANCE_MANTIS;
+	else if (!str_cmp(arg1, "dragon"))
+		pos = STANCE_DRAGON;
+	else if (!str_cmp(arg1, "tiger"))
+		pos = STANCE_TIGER;
+	else if (!str_cmp(arg1, "monkey"))
+		pos = STANCE_MONKEY;
+	else if (!str_cmp(arg1, "swallow"))
+		pos = STANCE_SWALLOW;
+	else
+	{
+		chprintlnf(ch, "%s: invalid stance.", n_fun);
+		return FALSE;
+	}
+
+	temp = atoi(arg2);
+	if (temp < -1 || temp > 200)
+	{
+		chprintlnf(ch, "%s: value must be between -1 and 200.", n_fun);
+		return FALSE;
+	}
+
+	if (validator && !validator(ch, &temp))
+		return FALSE;
+
+	(*value)[pos] = temp;
+	chprintlnf(ch, "%s: slot %d = '%s': Ok.", n_fun, pos, arg2);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_stats)
+{
+	int **value = (int **) arg;
+	int pos, temp;
+	char *stat;
+	char arg1[MIL], arg2[MIL];
+
+	argument = one_argument(argument, arg1);
+	one_argument(argument, arg2);
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
+	{
+		chprintlnf(ch, "Syntax: %s <str|int|wis|dex|con> <value>", n_fun);
+		return FALSE;
+	}
+
+	switch (UPPER(arg1[0]))
+	{
+	case 'S':
+		stat = "str";
+		pos = STAT_STR;
+		break;
+	case 'I':
+		stat = "int";
+		pos = STAT_INT;
+		break;
+	case 'W':
+		stat = "wis";
+		pos = STAT_WIS;
+		break;
+	case 'D':
+		stat = "dex";
+		pos = STAT_DEX;
+		break;
+	case 'C':
+		stat = "con";
+		pos = STAT_CON;
+		break;
+	default:
+		chprintlnf(ch, "%s: invalid stat.", n_fun);
+		return FALSE;
+		break;
+	}
+
+	temp = atoi(arg2);
+	if (temp < 0 || temp > 25)
+	{
+		chprintlnf(ch, "%s: value must be between 0 and 25.", n_fun);
+		return FALSE;
+	}
+
+	if (validator && !validator(ch, &temp))
+		return FALSE;
+
+	(*value)[pos] = temp;
+	chprintlnf(ch, "%s: %s = '%d': Ok.", n_fun, stat, temp);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_deity)
+{
+	DEITY_DATA **value = (DEITY_DATA **) arg;
+	DEITY_DATA *temp;
+	char arg1[MIL];
+
+	one_argument(argument, arg1);
+	if (IS_NULLSTR(arg1))
+	{
+		chprintlnf(ch, "Syntax: %s <deity>", n_fun);
+		return FALSE;
+	}
+
+	if ((temp = deity_lookup(arg1)) == NULL)
+	{
+		chprintlnf(ch, "%s: invalid deity.", n_fun);
+		return FALSE;
+	}
+
+	*value = temp;
+	chprintlnf(ch, "%s: '%s': Ok.", n_fun, temp->name);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_getchar)
+{
+	CHAR_DATA **value = (CHAR_DATA **) arg;
+	CHAR_DATA *temp;
+	char arg1[MIL];
+
+	one_argument(argument, arg1);
+	if (IS_NULLSTR(arg1))
+	{
+		chprintlnf(ch, "Syntax: %s <name>", n_fun);
+		chprintlnf(ch, "      : %s none", n_fun);
+		return FALSE;
+	}
+
+	if (!str_cmp(arg1, "none"))
+	{
+		*value = NULL;
+		chprintlnf(ch, "%s: reset: Ok.", n_fun);
+		return TRUE;
+	}
+
+	if ((temp = get_char_world(ch, arg1)) == NULL)
+	{
+		chprintlnf(ch, "%s: invalid character.", n_fun);
+		return FALSE;
+	}
+
+	*value = temp;
+	chprintlnf(ch, "%s: '%s': Ok.", n_fun,
+			   IS_NPC(temp) ? temp->short_descr : temp->name);
+	return TRUE;
+}
+
+ED_FUN_DEC(olced_time)
+{
+	time_t *value = (time_t *) arg;
+	time_t temp;
+	char arg1[MIL];
+
+	argument = one_argument(argument, arg1);
+	temp = atol(arg1);
+
+	if (IS_NULLSTR(argument))
+	{
+		chprintlnf(ch, "Syntax: %s <number> days|hours|minutes|seconds", n_fun);
+		return FALSE;
+	}
+
+	if (!str_prefix(argument, "days"))
+		temp *= DAY;
+	else if (!str_prefix(argument, "hours"))
+		temp *= HOUR;
+	else if (!str_prefix(argument, "minutes"))
+		temp *= MINUTE;
+	else
+		temp *= SECOND;
+
+	if (validator && !validator(ch, &temp))
+		return FALSE;
+
+	*value = temp;
+	chprintlnf(ch, "%s: '%s': Ok.", n_fun, timestr(temp, FALSE));
 	return TRUE;
 }
diff -ur -x config -x o -x rom src/olc_class.c new/olc_class.c
--- src/olc_class.c	Tue May 27 02:46:36 2003
+++ new/olc_class.c	Sun Aug 31 19:23:20 2003
@@ -22,24 +22,16 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "olc.h"
 #include "lookup.h"
 #include "interp.h"
 #include "tables.h"
 
-#define CLEDIT(fun)     bool fun (CHAR_DATA *ch, const char *argument)
-
-CLEDIT(cledit_create)
+OLCED(cledit_create)
 {
 	int j, i = maxClass;
 	int x = 0;
@@ -96,7 +88,7 @@
 	return TRUE;
 }
 
-CLEDIT(cledit_delete)
+OLCED(cledit_delete)
 {
 	CLASS_DATA *pClass;
 
@@ -194,7 +186,7 @@
 	}
 }
 
-CLEDIT(cledit_show)
+OLCED(cledit_show)
 {
 	CLASS_DATA *pClass;
 	int i;
@@ -221,7 +213,7 @@
 	return TRUE;
 }
 
-CLEDIT(cledit_prime)
+OLCED(cledit_prime)
 {
 	CLASS_DATA *pClass;
 	char arg[MIL];
@@ -314,7 +306,7 @@
 	return TRUE;
 }
 
-CLEDIT(cledit_skill)
+OLCED(cledit_skill)
 {
 	int sn;
 	CLASS_DATA *pClass;
@@ -385,7 +377,7 @@
 	return TRUE;
 }
 
-CLEDIT(cledit_guilds)
+OLCED(cledit_guilds)
 {
 	int slot;
 	vnum_t guild;
diff -ur -x config -x o -x rom src/olc_cmd.c new/olc_cmd.c
--- src/olc_cmd.c	Tue May 27 02:46:36 2003
+++ new/olc_cmd.c	Sun Aug 31 19:23:20 2003
@@ -22,25 +22,17 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "olc.h"
 #include "tables.h"
 #include "recycle.h"
 
-const char *do_fun_name args((DO_FUN * fun));
-DO_FUN *do_fun_lookup args((const char *name));
-
-#define CMDEDIT(fun)    bool fun (CHAR_DATA *ch, const char *argument)
+PROTOTYPE(const char *do_fun_name, (DO_FUN *));
+PROTOTYPE(DO_FUN * do_fun_lookup, (const char *));
 
 CH_CMD(do_cmdcheck)
 {
@@ -127,7 +119,7 @@
 	return;
 }
 
-CMDEDIT(cmdedit_show)
+OLCED(cmdedit_show)
 {
 	CMD_DATA *pCmd;
 
@@ -145,7 +137,7 @@
 	return TRUE;
 }
 
-CMDEDIT(cmdedit_create)
+OLCED(cmdedit_create)
 {
 	CMD_DATA *pCmd;
 	char buf[MIL];
@@ -164,7 +156,7 @@
 	return TRUE;
 }
 
-CMDEDIT(cmdedit_dofun)
+OLCED(cmdedit_dofun)
 {
 	CMD_DATA *pCmd;
 	DO_FUN *fun;
@@ -196,7 +188,7 @@
 	return TRUE;
 }
 
-CMDEDIT(cmdedit_delete)
+OLCED(cmdedit_delete)
 {
 	CMD_DATA *pCmd;
 
@@ -222,7 +214,7 @@
 	return TRUE;
 }
 
-CMDEDIT(cmdedit_rearrange)
+OLCED(cmdedit_rearrange)
 {
 	CMD_DATA *pCmd, *iCmd, *tmp;
 	bool found = FALSE;
@@ -280,7 +272,7 @@
 	return TRUE;
 }
 
-CMDEDIT(cmdedit_name)
+OLCED(cmdedit_name)
 {
 	bool relocate;
 	CMD_DATA *pCmd;
diff -ur -x config -x o -x rom src/olc_deity.c new/olc_deity.c
--- src/olc_deity.c	Tue May 27 02:46:36 2003
+++ new/olc_deity.c	Sun Aug 31 19:23:20 2003
@@ -22,14 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "olc.h"
 #include "lookup.h"
@@ -37,34 +33,7 @@
 #include "globals.h"
 #include "tables.h"
 #include "recycle.h"
-
-#define DEDIT(fun)  bool fun(CHAR_DATA *ch, const char *argument)
-
-void dedit(CHAR_DATA * ch, char *argument)
-{
-	if (get_trust(ch) < MAX_LEVEL - 5)
-	{
-		chprintln(ch, "Insuffecient security to modify deity data");
-		edit_done(ch);
-		return;
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		dedit_show(ch, argument);
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, deity_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
+#include "tablesave.h"
 
 CH_CMD(do_dedit)
 {
@@ -84,16 +53,9 @@
 		return;
 	}
 
-	pDeity = deity_lookup(arg);
-
-	if (!pDeity || IS_NULLSTR(pDeity->name))
+	if (!str_cmp(arg, "save"))
 	{
-		chprintln(ch, "That deity does not exist.");
-		return;
-	}
-	else if (!str_cmp(arg, "save"))
-	{
-		save_deities();
+		rw_deities(action_write);
 		chprintln(ch, "Deity database saved.");
 		return;
 	}
@@ -110,12 +72,17 @@
 
 		return;
 	}
+	else if (!(pDeity = deity_lookup(arg)) || IS_NULLSTR(pDeity->name))
+	{
+		chprintln(ch, "That deity does not exist.");
+		return;
+	}
 
 	edit_start(ch, pDeity, ED_DEITY);
 	return;
 }
 
-DEDIT(dedit_show)
+OLCED(dedit_show)
 {
 	DEITY_DATA *pDeity;
 
@@ -129,7 +96,7 @@
 	return TRUE;
 }
 
-DEDIT(dedit_list)
+OLCED(dedit_list)
 {
 	DEITY_DATA *i;
 	bool found = FALSE;
@@ -144,7 +111,7 @@
 	return TRUE;
 }
 
-DEDIT(dedit_create)
+OLCED(dedit_create)
 {
 	DEITY_DATA *pDeity;
 	char buf[MIL];
@@ -162,7 +129,7 @@
 	return TRUE;
 }
 
-DEDIT(dedit_delete)
+OLCED(dedit_delete)
 {
 	DEITY_DATA *pDeity;
 
diff -ur -x config -x o -x rom src/olc_group.c new/olc_group.c
--- src/olc_group.c	Tue May 27 02:46:36 2003
+++ new/olc_group.c	Sun Aug 31 19:23:20 2003
@@ -22,15 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "olc.h"
 #include "lookup.h"
@@ -38,9 +32,7 @@
 #include "interp.h"
 #include "tables.h"
 
-#define GREDIT(fun) bool fun (CHAR_DATA *ch, const char *argument)
-
-GREDIT(gredit_show)
+OLCED(gredit_show)
 {
 	int x;
 	GROUP_DATA *pGroup;
@@ -61,7 +53,7 @@
 	return TRUE;
 }
 
-GREDIT(gredit_create)
+OLCED(gredit_create)
 {
 	int j, i = maxGroup;
 	int x = 0;
@@ -110,7 +102,7 @@
 	return TRUE;
 }
 
-GREDIT(gredit_ratings)
+OLCED(gredit_ratings)
 {
 	GROUP_DATA *pGroup;
 	int pClass, value;
@@ -147,7 +139,7 @@
 	return TRUE;
 }
 
-GREDIT(gredit_spells)
+OLCED(gredit_spells)
 {
 	GROUP_DATA *pGroup;
 	int i;
@@ -196,7 +188,7 @@
 	return TRUE;
 }
 
-GREDIT(gredit_delete)
+OLCED(gredit_delete)
 {
 	GROUP_DATA *pGroup;
 
Only in src: olc_mpcode.c
Only in new: olc_pcode.c
diff -ur -x config -x o -x rom src/olc_race.c new/olc_race.c
--- src/olc_race.c	Tue May 27 02:46:36 2003
+++ new/olc_race.c	Sun Aug 31 19:23:20 2003
@@ -22,15 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "olc.h"
 #include "lookup.h"
@@ -38,9 +32,7 @@
 #include "tables.h"
 #include "recycle.h"
 
-#define RAEDIT(fun)     bool fun (CHAR_DATA *ch, const char *argument)
-
-RAEDIT(raedit_create)
+OLCED(raedit_create)
 {
 	RACE_DATA *pRace;
 	char buf[MIL];
@@ -58,7 +50,7 @@
 	return TRUE;
 }
 
-RAEDIT(raedit_list)
+OLCED(raedit_list)
 {
 	RACE_DATA *i;
 	int count = 0;
@@ -80,7 +72,7 @@
 	return FALSE;
 }
 
-RAEDIT(raedit_show)
+OLCED(raedit_show)
 {
 	RACE_DATA *pRace;
 	int x;
@@ -145,7 +137,7 @@
 	return FALSE;
 }
 
-RAEDIT(raedit_classx)
+OLCED(raedit_classx)
 {
 
 	char clas[MSL];
@@ -192,7 +184,7 @@
 	return FALSE;
 }
 
-RAEDIT(raedit_skills)
+OLCED(raedit_skills)
 {
 
 	int x;
@@ -237,7 +229,7 @@
 
 }
 
-RAEDIT(raedit_stats)
+OLCED(raedit_stats)
 {
 	char str[MSL];
 	char inte[MSL];
@@ -304,7 +296,7 @@
 	return FALSE;
 }
 
-RAEDIT(raedit_mstats)
+OLCED(raedit_mstats)
 {
 	char str[MSL];
 	char inte[MSL];
@@ -371,7 +363,7 @@
 	return FALSE;
 }
 
-RAEDIT(raedit_delete)
+OLCED(raedit_delete)
 {
 	RACE_DATA *pRace;
 	CHAR_DATA *rch;
@@ -395,7 +387,7 @@
 			{
 				if (mch->race == pRace)
 				{
-					mch->race = race_lookup("unique");
+					mch->race = default_race;
 					SET_BIT(mch->area->area_flags, AREA_CHANGED);
 				}
 			}
@@ -406,9 +398,9 @@
 			if (rch->race == pRace)
 			{
 				if (IS_NPC(rch))
-					rch->race = race_lookup("unique");
+					rch->race = default_race;
 				else
-					rch->race = race_lookup("human");
+					rch->race = default_race;
 			}
 		}
 
@@ -422,7 +414,7 @@
 	return TRUE;
 }
 
-RAEDIT(raedit_name)
+OLCED(raedit_name)
 {
 	RACE_DATA *pRace;
 	MOB_INDEX_DATA *pMob;
diff -ur -x config -x o -x rom src/olc_save.c new/olc_save.c
--- src/olc_save.c	Tue May 27 02:46:36 2003
+++ new/olc_save.c	Sun Aug 31 19:23:20 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /**************************************************************************
@@ -46,16 +46,12 @@
  *  mob etc is part of that area.
  */
 
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "tables.h"
 #include "olc.h"
 #include "interp.h"
+#include "tablesave.h"
+#include "save.h"
 
 #define DIF(a,b) (~((~a)|(b)))
 
@@ -95,27 +91,27 @@
  Purpose:	Saves the listing of files to be loaded at startup.
  Called by:	do_asave(olc_save.c).
  ****************************************************************************/
-void save_area_list()
+void save_area_list(void)
 {
-	FILE_DATA *fp;
+	WRITE_DATA *fp;
 	AREA_DATA *pArea;
 
-	if ((fp = fopen_temp("area.lst")) == NULL)
+	if ((fp = open_write(AREA_LIST)) == NULL)
 	{
-		bug("Save_area_list: file_open", 0);
-		perror("area.lst");
+		bug("Save_area_list: file open");
+		log_error("area.lst");
 	}
 	else
 	{
-		fprintf(fp->file, "%s\n", HELP_FILE);
+		fprintf(fp->stream, "help.are\n");
 
 		for (pArea = area_first; pArea; pArea = pArea->next)
 		{
-			fprintf(fp->file, "%s\n", pArea->file_name);
+			fprintf(fp->stream, "%s\n", pArea->file_name);
 		}
 
-		fprintf(fp->file, "$\n");
-		fclose_temp(fp);
+		fprintf(fp->stream, "$\n");
+		close_write(fp);
 	}
 
 	return;
@@ -441,7 +437,7 @@
 				fprintf(fp, "V ");
 				break;
 			default:
-				bug("olc_save: Invalid Affect->where", 0);
+				bug("olc_save: Invalid Affect->where");
 				break;
 			}
 
@@ -524,10 +520,9 @@
 				}
 				for (door = 0; door < MAX_DIR; door++)	/* I hate this! */
 				{
-					if ((pExit = pRoomIndex->exit[door]) && pExit->u1.to_room)
+					if ((pExit = pRoomIndex->exit[door]) && pExit->u1.to_room
+						&& !IS_SET(pExit->rs_flags, EX_TEMP))
 					{
-						int locks = 0;
-
 						/* HACK : TO PREVENT EX_LOCKED etc without EX_ISDOOR
 						   to stop booting the mud */
 						if (IS_SET
@@ -551,46 +546,12 @@
 						else
 							REMOVE_BIT(pExit->rs_flags, EX_ISDOOR);
 
-						/* THIS SUCKS but it's backwards compatible */
-						/* NOTE THAT EX_NOCLOSE NOLOCK etc aren't being saved */
-						if (IS_SET
-							(pExit->rs_flags, EX_ISDOOR)
-							&&
-							(!IS_SET
-							 (pExit->rs_flags,
-							  EX_PICKPROOF))
-							&& (!IS_SET(pExit->rs_flags, EX_NOPASS)))
-							locks = 1;
-						if (IS_SET
-							(pExit->rs_flags, EX_ISDOOR)
-							&&
-							(IS_SET
-							 (pExit->rs_flags,
-							  EX_PICKPROOF))
-							&& (!IS_SET(pExit->rs_flags, EX_NOPASS)))
-							locks = 2;
-						if (IS_SET
-							(pExit->rs_flags, EX_ISDOOR)
-							&&
-							(!IS_SET
-							 (pExit->rs_flags,
-							  EX_PICKPROOF))
-							&& (IS_SET(pExit->rs_flags, EX_NOPASS)))
-							locks = 3;
-						if (IS_SET
-							(pExit->rs_flags, EX_ISDOOR)
-							&&
-							(IS_SET
-							 (pExit->rs_flags,
-							  EX_PICKPROOF))
-							&& (IS_SET(pExit->rs_flags, EX_NOPASS)))
-							locks = 4;
-
 						fprintf(fp, "D%d\n", pExit->orig_door);
 						fprintf(fp, "%s~\n", fix_string(pExit->description));
 						fprintf(fp, "%s~\n", pExit->keyword);
-						fprintf(fp, "%d %ld %ld\n",
-								locks, pExit->key, pExit->u1.to_room->vnum);
+						fprintf(fp, "%s %ld %ld\n",
+								fwrite_flags(pExit->rs_flags), pExit->key,
+								pExit->u1.to_room->vnum);
 					}
 				}
 				if (pRoomIndex->mana_rate != 100 ||
@@ -675,9 +636,9 @@
 				for (door = 0; door < MAX_DIR; door++)
 				{
 					if ((pExit = pRoomIndex->exit[door]) &&
-						pExit->u1.to_room &&
-						(IS_SET(pExit->rs_flags, EX_CLOSED)
-						 || IS_SET(pExit->rs_flags, EX_LOCKED)))
+						pExit->u1.to_room && !IS_SET(pExit->rs_flags, EX_TEMP)
+						&& (IS_SET(pExit->rs_flags, EX_CLOSED)
+							|| IS_SET(pExit->rs_flags, EX_LOCKED)))
 #if defined( VERBOSE )
 						fprintf(fp,
 								"D 0 %d %d %d The %s door of %s is %s\n",
@@ -733,7 +694,7 @@
 					switch (pReset->command)
 					{
 					default:
-						bug("Save_resets: bad command %c.", pReset->command);
+						bugf("Save_resets: bad command %c.", pReset->command);
 						break;
 
 #if defined( VERBOSE )
@@ -782,7 +743,7 @@
 							sprintf(buf,
 									"Save_resets: !NO_MOB! in [%s]",
 									pArea->file_name);
-							bug(buf, 0);
+							bug(buf);
 						}
 						break;
 
@@ -802,7 +763,7 @@
 							sprintf(buf,
 									"Save_resets: !NO_MOB! in [%s]",
 									pArea->file_name);
-							bug(buf, 0);
+							bug(buf);
 						}
 						break;
 
@@ -812,8 +773,9 @@
 					case 'R':
 						pRoom = get_room_index(pReset->arg1);
 						fprintf(fp,
-								"R 0 %ld %d Randomize %s\n",
-								pReset->arg1, pReset->arg2, pRoom->name);
+								"R 0 %ld %d %ld Randomize %s\n",
+								pReset->arg1, pReset->arg2, pReset->arg3,
+								pRoom->name);
 						break;
 #endif
 #if !defined( VERBOSE )
@@ -847,7 +809,7 @@
 							sprintf(buf,
 									"Save_resets: !NO_MOB! in [%s]",
 									pArea->file_name);
-							bug(buf, 0);
+							bug(buf);
 						}
 						break;
 
@@ -859,7 +821,7 @@
 							sprintf(buf,
 									"Save_resets: !NO_MOB! in [%s]",
 									pArea->file_name);
-							bug(buf, 0);
+							bug(buf);
 						}
 						break;
 
@@ -868,7 +830,8 @@
 
 					case 'R':
 						pRoom = get_room_index(pReset->arg1);
-						fprintf(fp, "R 0 %ld %d\n", pReset->arg1, pReset->arg2);
+						fprintf(fp, "R 0 %ld %d %ld\n", pReset->arg1,
+								pReset->arg2, pReset->arg3);
 						break;
 #endif
 					}
@@ -928,24 +891,24 @@
 void save_helps(void)
 {
 	HELP_DATA *help;
-	FILE_DATA *fp;
+	WRITE_DATA *fp;
 
-	if ((fp = fopen_temp(HELP_FILE)) != NULL)
+	if ((fp = open_write(HELP_FILE)) != NULL)
 	{
-		fprintf(fp->file, "#HELPS\n");
+		fprintf(fp->stream, "#HELPS\n");
 
 		for (help = help_first; help; help = help->next)
 		{
-			fprintf(fp->file, "%d %s~\n", help->level, help->keyword);
-			fprintf(fp->file, "%s~\n\n", fix_string(help->text));
+			fprintf(fp->stream, "%d %s~\n", help->level, help->keyword);
+			fprintf(fp->stream, "%s~\n\n", fix_string(help->text));
 		}
 
-		fprintf(fp->file, "-1 $~\n\n");
-		fprintf(fp->file, "#$\n");
-		fclose_temp(fp);
+		fprintf(fp->stream, "-1 $~\n\n");
+		fprintf(fp->stream, "#$\n");
+		close_write(fp);
 	}
 	else
-		bug("Error opening " HELP_FILE ".", 0);
+		bug("Error opening " HELP_FILE ".");
 	return;
 }
 
@@ -956,43 +919,49 @@
  ****************************************************************************/
 void save_area(AREA_DATA * pArea)
 {
-	FILE_DATA *fp;
+	WRITE_DATA *fp;
+	char filename[512];
 
-	if (!(fp = fopen_temp(pArea->file_name)))
+	sprintf(filename, "%s%s", AREA_DIR, pArea->file_name);
+
+	if (!(fp = open_write(filename)))
 	{
-		bug("Open_area: file_open", 0);
-		perror(pArea->file_name);
+		bug("Open_area: file open");
+		log_error(pArea->file_name);
 	}
 	else
 	{
 		REMOVE_BIT(pArea->area_flags, AREA_CHANGED);
-		fprintf(fp->file, "#AREADATA\n");
-		fprintf(fp->file, "Name %s~\n", pArea->name);
-		fprintf(fp->file, "Builders %s~\n", fix_string(pArea->builders));
-		fprintf(fp->file, "VNUMs %ld %ld\n", pArea->min_vnum, pArea->max_vnum);
-		fprintf(fp->file, "Credits %s~\n", pArea->credits);
-		if (!IS_NULLSTR(pArea->lvl_comment))
-			fprintf(fp->file, "LvlComment %s~\n", pArea->lvl_comment);
-		fprintf(fp->file, "MinLevel %d\n", pArea->min_level);
-		fprintf(fp->file, "MaxLevel %d\n", pArea->max_level);
-		fprintf(fp->file, "Version %d\n", AREA_VERSION);
-		fprintf(fp->file, "Security %d\n", pArea->security);
-		fprintf(fp->file, "Flags %s\n", fwrite_flags(pArea->area_flags));
-		fprintf(fp->file, "End\n\n\n\n");
-
-		save_mobiles(fp->file, pArea);
-		save_objects(fp->file, pArea);
-		save_rooms(fp->file, pArea);
-		save_specials(fp->file, pArea);
-		save_resets(fp->file, pArea);
-		save_shops(fp->file, pArea);
-		save_mobprogs(fp->file, pArea);
-		save_objprogs(fp->file, pArea);
-		save_roomprogs(fp->file, pArea);
+		fprintf(fp->stream, "#AREADATA\n");
+		fwrite_string(fp->stream, "Name", pArea->name, NULL);
+		fwrite_string(fp->stream, "Builders", pArea->builders, NULL);
+		fprintf(fp->stream, "VNUMs\t\t%ld %ld\n", pArea->min_vnum,
+				pArea->max_vnum);
+		fwrite_string(fp->stream, "Credits", pArea->credits, NULL);
+		fwrite_string(fp->stream, "LvlComment", pArea->lvl_comment, NULL);
+		fwrite_int(fp->stream, "MinLevel", "%d", pArea->min_level, 0);
+		fwrite_int(fp->stream, "MaxLevel", "%d", pArea->max_level, MAX_LEVEL);
+		fwrite_int(fp->stream, "Version", "%d", AREA_VERSION, 0);
+		fwrite_int(fp->stream, "Security", "%d", pArea->security, 0);
+		fprintf(fp->stream, "Climate\t\t%d %d %d\n",
+				pArea->weather.climate_temp, pArea->weather.climate_precip,
+				pArea->weather.climate_wind);
+		fwrite_bit(fp->stream, "Flags", pArea->area_flags, 0);
+		fprintf(fp->stream, "End\n\n\n\n");
+
+		save_mobiles(fp->stream, pArea);
+		save_objects(fp->stream, pArea);
+		save_rooms(fp->stream, pArea);
+		save_specials(fp->stream, pArea);
+		save_resets(fp->stream, pArea);
+		save_shops(fp->stream, pArea);
+		save_mobprogs(fp->stream, pArea);
+		save_objprogs(fp->stream, pArea);
+		save_roomprogs(fp->stream, pArea);
 
-		fprintf(fp->file, "#$\n");
+		fprintf(fp->stream, "#$\n");
 
-		fclose_temp(fp);
+		close_write(fp);
 	}
 	return;
 }
@@ -1031,7 +1000,7 @@
 	smash_tilde(argument);
 	strcpy(arg1, argument);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		if (ch)
 		{
@@ -1041,15 +1010,10 @@
 			chprintln(ch, "  asave area     - saves the area being edited");
 			chprintln(ch, "  asave changed  - saves all changed zones");
 			chprintln(ch, "  asave world    - saves the world! (db dump)");
-			chprintln(ch, "  asave clans    - saves clan data");
-			chprintln(ch, "  asave commands - saves command data");
-			chprintln(ch, "  asave skills   - saves skill data");
-			chprintln(ch, "  asave groups   - saves group data");
-			chprintln(ch, "  asave races    - saves race data");
-			chprintln(ch, "  asave classes  - saves class data");
-			chprintln(ch, "  asave socials  - saves social data");
-			chprintln(ch, "  asave helps    - saves the help file");
-			chprintln(ch, "  asave deity    - save deity data");
+			for (value = 0; data_save_table[value].name != NULL; value++)
+				chprintlnf(ch, "  asave %-8s - saves %s data",
+						   data_save_table[value].name,
+						   data_save_table[value].name);
 			chprintln(ch, "");
 		}
 
@@ -1159,69 +1123,15 @@
 		return;
 	}
 
-	if (!str_cmp(arg1, "clans"))
-	{
-		save_clans();
-		chprint(ch, "Clans saved.");
-		return;
-	}
-
-	if (!str_cmp(arg1, "socials"))
-	{
-		save_social_table();
-		chprintln(ch, "Socials saved.");
-		return;
-	}
-
-	if (!str_cmp(arg1, "helps"))
-	{
-		save_area_list();
-		save_helps();
-		chprintln(ch, "Helps saved.");
-		return;
-	}
-
-	if (!str_cmp(arg1, "deity"))
-	{
-		save_deities();
-		if (ch)
-			chprintln(ch, "Deity data saved.");
-		return;
-	}
-
-	if (!str_cmp(arg1, "commands"))
-	{
-		save_commands();
-		chprintln(ch, "Commands saved.");
-		return;
-	}
-
-	if (!str_cmp(arg1, "skills"))
-	{
-		save_skills();
-		chprintln(ch, "Skills saved.");
-		return;
-	}
-
-	if (!str_cmp(arg1, "groups"))
+	for (value = 0; data_save_table[value].name != NULL; value++)
 	{
-		save_groups();
-		chprintln(ch, "Groups saved.");
-		return;
-	}
-
-	if (!str_cmp(arg1, "races"))
-	{
-		save_races();
-		chprintln(ch, "Races saved.");
-		return;
-	}
-
-	if (!str_cmp(arg1, "classes"))
-	{
-		save_classes();
-		chprintln(ch, "Classes saved.");
-		return;
+		if (!str_cmp(arg1, data_save_table[value].name))
+		{
+			(*data_save_table[value].fun) (action_write);
+			chprintlnf(ch, "%s data saved.",
+					   capitalize(data_save_table[value].name));
+			return;
+		}
 	}
 
 	/* Save area being edited, if authorized. */
diff -ur -x config -x o -x rom src/olc_skill.c new/olc_skill.c
--- src/olc_skill.c	Tue May 27 02:46:36 2003
+++ new/olc_skill.c	Sun Aug 31 19:23:20 2003
@@ -22,15 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "olc.h"
 #include "lookup.h"
@@ -40,10 +34,8 @@
 #include "magic.h"
 #include "gsn.h"
 
-const char *spell_fun_name args((SPELL_FUN * fun));
-const char *skill_gsn_name args((int *pgsn));
-
-#define SKEDIT(fun) bool fun (CHAR_DATA *ch, const char *argument)
+PROTOTYPE(const char *spell_fun_name, (SPELL_FUN *));
+PROTOTYPE(const char *skill_gsn_name, (int *));
 
 CH_CMD(do_skcheck)
 {
@@ -106,7 +98,7 @@
 	return;
 }
 
-SKEDIT(skedit_show)
+OLCED(skedit_show)
 {
 	int x;
 	SKILL_DATA *pSkill;
@@ -139,7 +131,7 @@
 	return TRUE;
 }
 
-SKEDIT(skedit_create)
+OLCED(skedit_create)
 {
 	int j, i = maxSkill;
 	SKILL_DATA *pSkill;
@@ -173,7 +165,7 @@
 	skill_table[i].spell_fun = spell_null;
 	skill_table[i].pgsn = &gsn_null;
 	skill_table[i].min_mana = 0;
-	skill_table[i].target = 0;
+	skill_table[i].target = TAR_IGNORE;
 	skill_table[i].minimum_position = POS_STANDING;
 	skill_table[i].beats = 0;
 	skill_table[i].noun_damage = str_empty;
@@ -194,7 +186,7 @@
 	return TRUE;
 }
 
-SKEDIT(skedit_levels)
+OLCED(skedit_levels)
 {
 	SKILL_DATA *pSkill;
 	char arg1[MIL], arg2[MIL];
@@ -230,7 +222,7 @@
 	return TRUE;
 }
 
-SKEDIT(skedit_ratings)
+OLCED(skedit_ratings)
 {
 	SKILL_DATA *pSkill;
 	int pClass, lev;
@@ -267,7 +259,7 @@
 	return TRUE;
 }
 
-SKEDIT(skedit_spellfun)
+OLCED(skedit_spellfun)
 {
 	SKILL_DATA *pSkill;
 	int i;
@@ -302,7 +294,7 @@
 	return FALSE;
 }
 
-SKEDIT(skedit_gsn)
+OLCED(skedit_gsn)
 {
 	SKILL_DATA *pSkill;
 	int i;
@@ -337,7 +329,7 @@
 	return FALSE;
 }
 
-SKEDIT(skedit_delete)
+OLCED(skedit_delete)
 {
 	SKILL_DATA *pSkill;
 
diff -ur -x config -x o -x rom src/olc_social.c new/olc_social.c
--- src/olc_social.c	Tue May 27 02:46:36 2003
+++ new/olc_social.c	Sun Aug 31 19:23:20 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
@@ -33,19 +33,11 @@
 
 /* This version contains minor modifications to support ROM 2.4b4. */
 
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "db.h"
 #include "olc.h"
 #include "recycle.h"
 
-#define SEDIT( fun )		bool fun( CHAR_DATA *ch, const char *argument )
-
 /* Find a social based on name */
 SOCIAL_DATA *social_lookup(const char *name)
 {
@@ -62,7 +54,7 @@
  * Social editting command
  */
 
-SEDIT(sedit_show)
+OLCED(sedit_show)
 {
 	SOCIAL_DATA *pSocial;
 
@@ -77,10 +69,6 @@
 		return FALSE;
 	}
 
-	chprintf(ch, "%s\n\r",
-			 stringf(ch, 0, ALIGN_CENTER, "-",
-					 FORMATF("[ %s: %s ]", olc_ed_name(ch), olc_ed_vnum(ch))));
-
 	chprintf(ch, "Name    : %s\n\r"
 			 "(cnoarg): %s\n\r" "(onoarg): %s\n\r"
 			 "(cfound): %s\n\r" "(ofound): %s\n\r"
@@ -94,11 +82,10 @@
 			 IS_STRSET(pSocial->vict_found),
 			 IS_STRSET(pSocial->char_auto), IS_STRSET(pSocial->others_auto));
 
-	chprintln(ch, draw_line(ch, NULL, 0));
 	return TRUE;
 }
 
-SEDIT(sedit_delete)
+OLCED(sedit_delete)
 {
 	SOCIAL_DATA *pSocial;
 
@@ -120,7 +107,7 @@
 	return TRUE;
 }
 
-SEDIT(sedit_create)
+OLCED(sedit_create)
 {
 	SOCIAL_DATA *pSocial;
 	char arg[MAX_INPUT_LENGTH];
@@ -145,31 +132,6 @@
 	return TRUE;
 }
 
-void sedit(CHAR_DATA * ch, char *argument)
-{
-	if (ch->pcdata->security < 5)
-	{
-		chprintln(ch, "SEdit: Insufficient security to modify socials.");
-		edit_done(ch);
-	}
-
-	if (!str_cmp(argument, "done"))
-	{
-		edit_done(ch);
-		return;
-	}
-
-	if (emptystring(argument))
-	{
-		sedit_show(ch, "");
-		return;
-	}
-
-	if (!process_olc_command(ch, argument, social_olc_comm_table))
-		interpret(ch, argument);
-	return;
-}
-
 CH_CMD(do_sedit)
 {
 	SOCIAL_DATA *pSocial;
@@ -238,7 +200,7 @@
 	return;
 }
 
-SEDIT(sedit_name)
+OLCED(sedit_name)
 {
 	bool relocate;
 	SOCIAL_DATA *psocial;
Only in new: olc_song.c
Only in new: prog_cmds.c
Only in new: prog_cmds.h
Only in new: programs.c
diff -ur -x config -x o -x rom src/proto.h new/proto.h
--- src/proto.h	Tue May 27 02:46:36 2003
+++ new/proto.h	Sun Aug 31 19:23:21 2003
@@ -22,591 +22,614 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /*
  * Our function prototypes.
- * One big lump ... this is every function in Merc.
+ * One big lump ... this is almost every function in 1stMUD.
  */
-#define CD	CHAR_DATA
-#define MID	MOB_INDEX_DATA
-#define OD	OBJ_DATA
-#define OID	OBJ_INDEX_DATA
-#define RID	ROOM_INDEX_DATA
-#define SF	SPEC_FUN
-#define AD	AFFECT_DATA
-#define PC	PROG_CODE
+
+#if !defined(PROTOTYPE_H)
+#define PROTOTYPE_H
+
+#if !defined(__GNUC__)
+#define __attribute__(x)		/* nothing */
+#endif
+
+#define PROTOTYPE(x,y) EXTERN x y
+#define PROTOTYPEF(x,y,a,b) EXTERN x y __attribute__((format(printf, a, b)))
 
 /* act_comm.c */
-void check_sex args((CHAR_DATA * ch));
-void add_follower args((CHAR_DATA * ch, CHAR_DATA * master));
-void stop_follower args((CHAR_DATA * ch));
-void nuke_pets args((CHAR_DATA * ch));
-void die_follower args((CHAR_DATA * ch));
-bool is_same_group args((CHAR_DATA * ach, CHAR_DATA * bch));
-int colour_lookup args((const char *arg));
-int cslot_lookup args((const char *arg));
-const char *char_colour args((CHAR_DATA * ch, int slot));
-void default_colour args((CHAR_DATA * ch, int slot));
-bool check_cstring args((char *string));
-char *random_colour args((void));
-char *random_background args((void));
-void show_greeting args((DESCRIPTOR_DATA * dnew));
-bool process_ansi_output args((DESCRIPTOR_DATA * d));
-const char *color_default args((CHAR_DATA * ch));
-
-const char *color_to_tilde args((const char *str));
-const char *tilde_to_color args((const char *str));
-unsigned int strlen_color args((const char *string));
-const char *draw_line args((CHAR_DATA * ch, char *fill, int len));
-const char *smash_colour args((const char *str));
-const char *stringf
-args(
-	 (CHAR_DATA * ch, int length, int align, const char *fill,
-	  const char *string));
-bool is_ansi_printed_char args((char c));
-
-void public_ch args((CHAR_DATA * ch, const char *argument,
-					 const char *type, flag_t bitname,
-					 enum special_flags spec_flag, int last_type));
+PROTOTYPE(void check_sex, (CHAR_DATA *));
+PROTOTYPE(void add_follower, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void stop_follower, (CHAR_DATA *));
+PROTOTYPE(void nuke_pets, (CHAR_DATA *));
+PROTOTYPE(void die_follower, (CHAR_DATA *));
+PROTOTYPE(bool is_same_group, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(int colour_lookup, (const char *));
+PROTOTYPE(int cslot_lookup, (const char *));
+PROTOTYPE(const char *char_colour, (CHAR_DATA *, int));
+PROTOTYPE(void default_colour, (CHAR_DATA *, int));
+PROTOTYPE(bool check_cstring, (char *));
+PROTOTYPE(char *random_colour, (void));
+PROTOTYPE(char *random_background, (void));
+PROTOTYPE(void show_greeting, (DESCRIPTOR_DATA *));
+PROTOTYPE(bool process_ansi_output, (DESCRIPTOR_DATA *));
+PROTOTYPE(const char *color_default, (CHAR_DATA *));
+
+PROTOTYPE(const char *color_to_tilde, (const char *));
+PROTOTYPE(const char *tilde_to_color, (const char *));
+PROTOTYPE(unsigned int strlen_color, (const char *));
+PROTOTYPE(const char *draw_line, (CHAR_DATA *, char *, int));
+PROTOTYPE(const char *smash_colour, (const char *));
+PROTOTYPE(const char *stringf, (CHAR_DATA *, int, int, const char *,
+								const char *));
+PROTOTYPE(bool is_ansi_printed_char, (char));
+
+PROTOTYPE(void public_ch, (CHAR_DATA *, const char *, int));
 
 /* act_enter.c */
-RID *get_random_room args((CHAR_DATA * ch));
+PROTOTYPE(ROOM_INDEX_DATA * get_random_room, (CHAR_DATA *));
 
 /* act_info.c */
-void set_title args((CHAR_DATA * ch, const char *title));
-char *format_who args((CHAR_DATA * ch, CHAR_DATA * wch));
+PROTOTYPE(void set_title, (CHAR_DATA *, const char *));
+PROTOTYPE(char *format_who, (CHAR_DATA *, CHAR_DATA *));
 
 /* act_move.c */
-void move_char args((CHAR_DATA * ch, int door, bool follow));
+PROTOTYPE(void move_char, (CHAR_DATA *, int, bool));
 
 /* act_obj.c */
-bool can_loot args((CHAR_DATA * ch, OBJ_DATA * obj));
-void wear_obj args((CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace));
-void get_obj args((CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * container));
-void recursive_clone args((CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * clone));
-bool obj_check args((CHAR_DATA * ch, OBJ_DATA * obj));
+PROTOTYPE(bool can_loot, (CHAR_DATA *, OBJ_DATA *));
+PROTOTYPE(void wear_obj, (CHAR_DATA *, OBJ_DATA *, bool));
+PROTOTYPE(void get_obj, (CHAR_DATA *, OBJ_DATA *, OBJ_DATA *));
+PROTOTYPE(void recursive_clone, (CHAR_DATA *, OBJ_DATA *, OBJ_DATA *));
+PROTOTYPE(bool obj_check, (CHAR_DATA *, OBJ_DATA *));
 
 /* act_wiz.c */
-void wiznet
-args((char *string, CHAR_DATA * ch, OBJ_DATA * obj, flag_t flag,
-	  flag_t flag_skip, int min_level));
-#if !defined(WIN32) && !defined(__CYGWIN__)
-void copyover_recover args((void));
+PROTOTYPEF(void new_wiznet, (CHAR_DATA *, OBJ_DATA *, flag_t,
+							 flag_t, int, const char *, ...), 6, 7);
+
+#if !defined(NO_COPYOVER)
+PROTOTYPE(void copyover_recover, (void));
+PROTOTYPE(void copyover, (void));
 #endif
 
 /* alias.c */
-void substitute_alias args((DESCRIPTOR_DATA * d, char *input));
+PROTOTYPE(void substitute_alias, (DESCRIPTOR_DATA *, char *));
 
 /* ban.c */
-bool check_ban args((const char *site, int type));
-void save_bans args((void));
-void load_bans args((void));
-void ban_site args((CHAR_DATA * ch, const char *argument, bool fPerm));
+PROTOTYPE(bool check_ban, (const char *, int));
+PROTOTYPE(void ban_site, (CHAR_DATA *, const char *));
 
 /* comm.c */
-void show_string args((struct descriptor_data * d, char *input));
-void close_socket args((DESCRIPTOR_DATA * dclose));
-void write_to_buffer args((DESCRIPTOR_DATA * d, const char *txt, int length));
-void chprint args((CHAR_DATA * ch, const char *txt));
-void chprintln args((CHAR_DATA * ch, const char *txt));
-void page_to_char args((const char *txt, CHAR_DATA * ch));
-void act
-args((const char *format, CHAR_DATA * ch, const void *arg1,
-	  const void *arg2, int type));
-void act_new
-args((const char *format, CHAR_DATA * ch, const void *arg1,
-	  const void *arg2, flag_t type, int min_pos));
-void perform_act args((const char *orig, CHAR_DATA * ch, const void *arg1,
-					   const void *arg2, flag_t type, CHAR_DATA * to));
-const char *perform_act_string
-args(
-	 (const char *orig, CHAR_DATA * ch, const void *arg1, const void *arg2,
-	  bool cReturn));
-
-void chprintf args((CHAR_DATA *, char *, ...))
-	__attribute__ ((format(printf, 2, 3)));
-void chprintlnf args((CHAR_DATA *, char *, ...))
-	__attribute__ ((format(printf, 2, 3)));
-void bugf args((char *, ...)) __attribute__ ((format(printf, 1, 2)));
-void fix_sex args((CHAR_DATA * ch));
-void logf args((char *fmt, ...)) __attribute__ ((format(printf, 1, 2)));
-void vinterpret args((CHAR_DATA * ch, const char *argument, ...))
-	__attribute__ ((format(printf, 2, 3)));
-int strswitch args((const char *arg, ...))
-	__attribute__ ((format(printf, 1, 2)));
+PROTOTYPE(void show_string, (DESCRIPTOR_DATA *, char *));
+PROTOTYPE(void close_socket, (DESCRIPTOR_DATA *));
+PROTOTYPE(void d_print, (DESCRIPTOR_DATA *, const char *, int));
+PROTOTYPE(void d_println, (DESCRIPTOR_DATA *, const char *, int));
+PROTOTYPEF(void d_printf, (DESCRIPTOR_DATA *, const char *, ...), 2, 3);
+PROTOTYPEF(void d_printlnf, (DESCRIPTOR_DATA *, const char *, ...), 2, 3);
+PROTOTYPE(void chprint, (CHAR_DATA *, const char *));
+PROTOTYPE(void chprintln, (CHAR_DATA *, const char *));
+PROTOTYPE(void sendpage, (CHAR_DATA *, const char *));
+PROTOTYPE(void act_new, (const char *, CHAR_DATA *, const void *,
+						 const void *, flag_t, position_t));
+PROTOTYPE(void perform_act, (const char *, CHAR_DATA *, const void *,
+							 const void *, flag_t, CHAR_DATA *));
+PROTOTYPE(const char *perform_act_string,
+		  (const char *, CHAR_DATA *, const void *, const void *, bool));
+
+PROTOTYPEF(void chprintf, (CHAR_DATA *, const char *, ...), 2, 3);
+PROTOTYPEF(void chprintlnf, (CHAR_DATA *, const char *, ...), 2, 3);
+PROTOTYPEF(void bugf, (const char *, ...), 1, 2);
+PROTOTYPE(void fix_sex, (CHAR_DATA *));
+PROTOTYPEF(void logf, (const char *, ...), 1, 2);
+PROTOTYPEF(void vinterpret, (CHAR_DATA *, const char *, ...), 2, 3);
+PROTOTYPEF(int strswitch, (const char *, ...), 1, 2);
 
 /* db.c */
-void reset_area args((AREA_DATA * pArea));	/* OLC */
-void reset_room args((ROOM_INDEX_DATA * pRoom));	/* OLC */
-char *fwrite_flags(flag_t flags);
-void boot_db args((void));
-void area_update args((void));
-CD *create_mobile args((MOB_INDEX_DATA * pMobIndex));
-void clone_mobile args((CHAR_DATA * parent, CHAR_DATA * clone));
-OD *create_object args((OBJ_INDEX_DATA * pObjIndex, int level));
-void clone_object args((OBJ_DATA * parent, OBJ_DATA * clone));
-void clear_char args((CHAR_DATA * ch));
-const char *get_extra_descr args((const char *name, EXTRA_DESCR_DATA * ed));
-MID *get_mob_index args((vnum_t vnum));
-OID *get_obj_index args((vnum_t vnum));
-RID *get_room_index args((vnum_t vnum));
-PC *get_prog_index args((vnum_t vnum, int type));
-char fread_letter args((FILE * fp));
-int fread_number args((FILE * fp));
-flag_t fread_flag args((FILE * fp));
-const char *fread_string args((FILE * fp));
-const char *freadline args((FILE * fp));
-void fread_to_eol args((FILE * fp));
-char *fread_word args((FILE * fp));
-flag_t flag_convert args((char letter));
-const char *str_dup args((const char *pstr));
-void free_string args((const char *pstr));
-int number_fuzzy args((int number));
-int number_fuzzier args((int number));
-int number_range args((int from, int to));
-int number_percent args((void));
-int number_door args((void));
-int number_bits args((int width));
-long number_mm args((void));
-int dice args((int number, int size));
-int interpolate args((int level, int value_00, int value_32));
-void smash_tilde args((const char *str));
-int str_cmp args((const char *astr, const char *bstr));
-int str_casecmp args((const char *astr, const char *bstr));
-int str_ncmp args((const char *astr, const char *bstr, size_t len));
-int str_ncasecmp args((const char *astr, const char *bstr, size_t len));
-bool str_prefix args((const char *astr, const char *bstr));
-bool str_infix args((const char *astr, const char *bstr));
-bool str_suffix args((const char *astr, const char *bstr));
-char *capitalize args((const char *str));
-void append_file args((CHAR_DATA * ch, char *file, const char *str));
-void bug args((const char *str, int param));
-void log_string args((const char *str));
-void tail_chain args((void));
-void new_reset args((ROOM_INDEX_DATA * pR, RESET_DATA * pReset));
+PROTOTYPE(void reset_area, (AREA_DATA *));	/* OLC */
+PROTOTYPE(void reset_room, (ROOM_INDEX_DATA *));	/* OLC */
+PROTOTYPE(char *fwrite_flags, (flag_t));
+PROTOTYPE(void boot_db, (void));
+PROTOTYPE(void area_update, (void));
+PROTOTYPE(CHAR_DATA * create_mobile, (MOB_INDEX_DATA *));
+PROTOTYPE(void clone_mobile, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(OBJ_DATA * create_object, (OBJ_INDEX_DATA *, int));
+PROTOTYPE(void clone_object, (OBJ_DATA *, OBJ_DATA *));
+PROTOTYPE(void clear_char, (CHAR_DATA *));
+PROTOTYPE(const char *get_extra_descr, (const char *, EXTRA_DESCR_DATA *));
+PROTOTYPE(MOB_INDEX_DATA * get_mob_index, (vnum_t));
+PROTOTYPE(OBJ_INDEX_DATA * get_obj_index, (vnum_t));
+PROTOTYPE(ROOM_INDEX_DATA * get_room_index, (vnum_t));
+PROTOTYPE(PROG_CODE * get_prog_index, (vnum_t, prog_t));
+
+PROTOTYPE(char fread_letter, (FILE *));
+PROTOTYPE(int fread_number, (FILE *));
+PROTOTYPE(flag_t fread_flag, (FILE *));
+PROTOTYPE(const char *fread_string, (FILE *));
+PROTOTYPE(const char *fread_line, (FILE *));
+PROTOTYPE(const char *fread_file, (FILE *));
+PROTOTYPE(void fread_to_eol, (FILE *));
+PROTOTYPE(char *fread_word, (FILE *));
+
+PROTOTYPE(char read_letter, (READ_DATA *));
+PROTOTYPE(int read_number, (READ_DATA *));
+PROTOTYPE(flag_t read_flag, (READ_DATA *));
+PROTOTYPE(const char *read_string, (READ_DATA *));
+PROTOTYPE(const char *read_line, (READ_DATA *));
+PROTOTYPE(void read_to_eol, (READ_DATA *));
+PROTOTYPE(char *read_word, (READ_DATA *));
+
+PROTOTYPE(flag_t flag_convert, (char));
+PROTOTYPE(const char *str_dup, (const char *));
+PROTOTYPE(void _free_string, (const char *));
+PROTOTYPE(int number_fuzzy, (int));
+PROTOTYPE(int number_fuzzier, (int));
+PROTOTYPE(int number_range, (int, int));
+PROTOTYPE(int number_percent, (void));
+PROTOTYPE(int number_door, (void));
+PROTOTYPE(int number_bits, (int));
+PROTOTYPE(long number_mm, (void));
+PROTOTYPE(int dice, (int, int));
+PROTOTYPE(int interpolate, (int, int, int));
+PROTOTYPE(void smash_tilde, (const char *));
+PROTOTYPE(int str_cmp, (const char *, const char *));
+PROTOTYPE(int str_casecmp, (const char *, const char *));
+PROTOTYPE(int str_ncmp, (const char *, const char *, size_t));
+PROTOTYPE(int str_ncasecmp, (const char *, const char *, size_t));
+PROTOTYPE(bool str_prefix, (const char *, const char *));
+PROTOTYPE(bool str_infix, (const char *, const char *));
+PROTOTYPE(bool str_suffix, (const char *, const char *));
+PROTOTYPE(char *capitalize, (const char *));
+PROTOTYPE(void append_file, (CHAR_DATA *, char *, const char *));
+PROTOTYPE(void bug, (const char *));
+PROTOTYPE(void log_string, (const char *));
+PROTOTYPE(void tail_chain, (void));
+PROTOTYPE(void new_reset, (ROOM_INDEX_DATA *, RESET_DATA *));
 
 /* db2.c */
-void load_socials args((FILE * fp));
-void load_mobiles args((FILE * fp));
-void load_objects args((FILE * fp));
-FILE *file_open args((const char *file, const char *mode));
-bool file_close args((FILE * fp));
-void free_runbuf args((DESCRIPTOR_DATA * d));
-FILE_DATA *fopen_temp args((const char *file));
-void fclose_temp args((FILE_DATA * fp));
+PROTOTYPE(void load_mobiles, (READ_DATA *));
+PROTOTYPE(void load_objects, (READ_DATA *));
+PROTOTYPE(FILE * file_open, (const char *, const char *));
+PROTOTYPE(void file_close, (FILE *));
+PROTOTYPE(void free_runbuf, (DESCRIPTOR_DATA *));
+PROTOTYPEF(WRITE_DATA * open_write, (const char *,...), 1, 2);
+PROTOTYPE(void close_write, (WRITE_DATA *));
+PROTOTYPEF(READ_DATA * open_read, (const char *path,...), 1, 2);
+PROTOTYPE(void close_read, (READ_DATA *));
+PROTOTYPEF(WRITE_DATA * open_append, (const char *,...), 1, 2);
+PROTOTYPE(void close_append, (WRITE_DATA *));
 
 /* effect.c */
-void acid_effect args((void *vo, int level, int dam, int target));
-void cold_effect args((void *vo, int level, int dam, int target));
-void fire_effect args((void *vo, int level, int dam, int target));
-void poison_effect args((void *vo, int level, int dam, int target));
-void shock_effect args((void *vo, int level, int dam, int target));
+PROTOTYPE(void acid_effect, (void *, int, int, int));
+PROTOTYPE(void cold_effect, (void *, int, int, int));
+PROTOTYPE(void fire_effect, (void *, int, int, int));
+PROTOTYPE(void poison_effect, (void *, int, int, int));
+PROTOTYPE(void shock_effect, (void *, int, int, int));
 
 /* fight.c */
-bool is_safe args((CHAR_DATA * ch, CHAR_DATA * victim));
-bool is_safe_spell args((CHAR_DATA * ch, CHAR_DATA * victim, bool area));
-void violence_update args((void));
-void multi_hit args((CHAR_DATA * ch, CHAR_DATA * victim, int dt));
-bool damage
-args((CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, int Class,
-	  bool show));
-bool damage_old
-args((CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, int Class,
-	  bool show));
-void update_pos args((CHAR_DATA * victim));
-void stop_fighting args((CHAR_DATA * ch, bool fBoth));
-void check_killer args((CHAR_DATA * ch, CHAR_DATA * victim));
+PROTOTYPE(bool is_safe, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool is_safe_spell, (CHAR_DATA *, CHAR_DATA *, bool));
+PROTOTYPE(void violence_update, (void));
+PROTOTYPE(void multi_hit, (CHAR_DATA *, CHAR_DATA *, int));
+PROTOTYPE(bool damage, (CHAR_DATA *, CHAR_DATA *, int, int, int, bool));
+PROTOTYPE(void update_pos, (CHAR_DATA *));
+PROTOTYPE(void stop_fighting, (CHAR_DATA *, bool));
+PROTOTYPE(void check_killer, (CHAR_DATA *, CHAR_DATA *));
 
 /* handler.c */
-AD *affect_find args((AFFECT_DATA * paf, int sn));
-void affect_check args((CHAR_DATA * ch, int where, flag_t vector));
-int count_users args((OBJ_DATA * obj));
-void deduct_cost args((CHAR_DATA * ch, int cost));
-void affect_enchant args((OBJ_DATA * obj));
-int check_immune args((CHAR_DATA * ch, int dam_type));
-int material_lookup args((const char *name));
-int weapon_lookup args((const char *name));
-int weapon_typ args((const char *name));
-const char *weapon_name args((int weapon_Type));
-const char *item_name args((int pitem_type));
-int attack_lookup args((const char *name));
-int wiznet_lookup args((const char *name));
-int class_lookup args((const char *name));
-bool is_clan args((CHAR_DATA * ch));
-bool is_same_clan args((CHAR_DATA * ch, CHAR_DATA * victim));
-bool is_old_mob args((CHAR_DATA * ch));
-int get_skill args((CHAR_DATA * ch, int sn));
-int get_weapon_sn args((CHAR_DATA * ch));
-int get_weapon_skill args((CHAR_DATA * ch, int sn));
-int get_age args((CHAR_DATA * ch));
-void reset_char args((CHAR_DATA * ch));
-int get_trust args((CHAR_DATA * ch));
-int get_curr_stat args((CHAR_DATA * ch, int stat));
-int get_max_train args((CHAR_DATA * ch, int stat));
-int can_carry_n args((CHAR_DATA * ch));
-int can_carry_w args((CHAR_DATA * ch));
-bool is_name args((const char *str, const char *namelist));
-bool is_exact_name args((const char *str, const char *namelist));
-void affect_to_char args((CHAR_DATA * ch, AFFECT_DATA * paf));
-void affect_to_obj args((OBJ_DATA * obj, AFFECT_DATA * paf));
-void affect_remove args((CHAR_DATA * ch, AFFECT_DATA * paf));
-void affect_remove_obj args((OBJ_DATA * obj, AFFECT_DATA * paf));
-void affect_strip args((CHAR_DATA * ch, int sn));
-bool is_affected args((CHAR_DATA * ch, int sn));
-void affect_join args((CHAR_DATA * ch, AFFECT_DATA * paf));
-void char_from_room args((CHAR_DATA * ch));
-void char_to_room args((CHAR_DATA * ch, ROOM_INDEX_DATA * pRoomIndex));
-void obj_to_char args((OBJ_DATA * obj, CHAR_DATA * ch));
-void obj_from_char args((OBJ_DATA * obj));
-int apply_ac args((OBJ_DATA * obj, int iWear, int type));
-OD *get_eq_char args((CHAR_DATA * ch, int iWear));
-void equip_char args((CHAR_DATA * ch, OBJ_DATA * obj, int iWear));
-void unequip_char args((CHAR_DATA * ch, OBJ_DATA * obj));
-int count_obj_list args((OBJ_INDEX_DATA * obj, OBJ_DATA * list));
-void obj_from_room args((OBJ_DATA * obj));
-void obj_to_room args((OBJ_DATA * obj, ROOM_INDEX_DATA * pRoomIndex));
-void obj_to_obj args((OBJ_DATA * obj, OBJ_DATA * obj_to));
-void obj_from_obj args((OBJ_DATA * obj));
-void extract_obj args((OBJ_DATA * obj));
-void extract_char args((CHAR_DATA * ch, bool fPull));
-CD *get_char_room
-args((CHAR_DATA * ch, ROOM_INDEX_DATA * room, const char *argument));
-CD *get_char_world args((CHAR_DATA * ch, const char *argument));
-OD *get_obj_type args((OBJ_INDEX_DATA * pObjIndexData));
-OD *get_obj_list args((CHAR_DATA * ch, const char *argument, OBJ_DATA * list));
-OD *get_obj_carry
-args((CHAR_DATA * ch, const char *argument, CHAR_DATA * viewer));
-OD *get_obj_wear args((CHAR_DATA * ch, const char *argument, bool character));
-OD *get_obj_here
-args((CHAR_DATA * ch, ROOM_INDEX_DATA * room, const char *argument));
-OD *get_obj_world args((CHAR_DATA * ch, const char *argument));
-OD *create_money args((int gold, int silver));
-int get_obj_number args((OBJ_DATA * obj));
-int get_obj_weight args((OBJ_DATA * obj));
-int get_true_weight args((OBJ_DATA * obj));
-bool room_is_dark args((ROOM_INDEX_DATA * pRoomIndex));
-bool is_room_owner args((CHAR_DATA * ch, ROOM_INDEX_DATA * room));
-bool room_is_private args((ROOM_INDEX_DATA * pRoomIndex));
-bool can_see args((CHAR_DATA * ch, CHAR_DATA * victim));
-bool can_see_obj args((CHAR_DATA * ch, OBJ_DATA * obj));
-bool can_see_room args((CHAR_DATA * ch, ROOM_INDEX_DATA * pRoomIndex));
-bool can_drop_obj args((CHAR_DATA * ch, OBJ_DATA * obj));
-bool is_friend args((CHAR_DATA * ch, CHAR_DATA * victim));
-bool is_full_name args((const char *str, const char *namelist));
-CHAR_DATA *get_char_id args((long id));
+PROTOTYPE(AFFECT_DATA * affect_find, (AFFECT_DATA *, int));
+PROTOTYPE(void affect_check, (CHAR_DATA *, int, flag_t));
+PROTOTYPE(int count_users, (OBJ_DATA *));
+PROTOTYPE(void deduct_cost, (CHAR_DATA *, int));
+PROTOTYPE(void affect_enchant, (OBJ_DATA *));
+PROTOTYPE(int check_immune, (CHAR_DATA *, int));
+PROTOTYPE(int material_lookup, (const char *));
+PROTOTYPE(int weapon_lookup, (const char *));
+PROTOTYPE(int weapon_typ, (const char *));
+PROTOTYPE(const char *weapon_name, (int));
+PROTOTYPE(const char *item_name, (int));
+PROTOTYPE(int attack_lookup, (const char *));
+PROTOTYPE(int wiznet_lookup, (const char *));
+PROTOTYPE(int class_lookup, (const char *));
+PROTOTYPE(bool is_clan, (CHAR_DATA *));
+PROTOTYPE(bool is_same_clan, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool is_old_mob, (CHAR_DATA *));
+PROTOTYPE(int get_skill, (CHAR_DATA *, int));
+PROTOTYPE(int get_weapon_sn, (CHAR_DATA *));
+PROTOTYPE(int get_weapon_skill, (CHAR_DATA *, int));
+PROTOTYPE(int get_age, (CHAR_DATA *));
+PROTOTYPE(void reset_char, (CHAR_DATA *));
+PROTOTYPE(int get_trust, (CHAR_DATA *));
+PROTOTYPE(int get_curr_stat, (CHAR_DATA *, int));
+PROTOTYPE(int get_max_train, (CHAR_DATA *, int));
+PROTOTYPE(int can_carry_n, (CHAR_DATA *));
+PROTOTYPE(int can_carry_w, (CHAR_DATA *));
+PROTOTYPE(bool is_name, (const char *, const char *));
+PROTOTYPE(bool is_exact_name, (const char *, const char *));
+PROTOTYPE(void affect_to_char, (CHAR_DATA *, AFFECT_DATA *));
+PROTOTYPE(void affect_to_obj, (OBJ_DATA *, AFFECT_DATA *));
+PROTOTYPE(void affect_remove, (CHAR_DATA *, AFFECT_DATA *));
+PROTOTYPE(void affect_remove_obj, (OBJ_DATA *, AFFECT_DATA *));
+PROTOTYPE(void affect_strip, (CHAR_DATA *, int));
+PROTOTYPE(bool is_affected, (CHAR_DATA *, int));
+PROTOTYPE(void affect_join, (CHAR_DATA *, AFFECT_DATA *));
+PROTOTYPE(void char_from_room, (CHAR_DATA *));
+PROTOTYPE(void char_to_room, (CHAR_DATA *, ROOM_INDEX_DATA *));
+PROTOTYPE(void obj_to_char, (OBJ_DATA *, CHAR_DATA *));
+PROTOTYPE(void obj_from_char, (OBJ_DATA *));
+PROTOTYPE(int apply_ac, (OBJ_DATA *, wloc_t, int));
+PROTOTYPE(OBJ_DATA * get_eq_char, (CHAR_DATA *, wloc_t));
+PROTOTYPE(void equip_char, (CHAR_DATA *, OBJ_DATA *, wloc_t));
+PROTOTYPE(void unequip_char, (CHAR_DATA *, OBJ_DATA *));
+PROTOTYPE(int count_obj_list, (OBJ_INDEX_DATA *, OBJ_DATA *));
+PROTOTYPE(void obj_from_room, (OBJ_DATA *));
+PROTOTYPE(void obj_to_room, (OBJ_DATA *, ROOM_INDEX_DATA *));
+PROTOTYPE(void obj_to_obj, (OBJ_DATA *, OBJ_DATA *));
+PROTOTYPE(void obj_from_obj, (OBJ_DATA *));
+PROTOTYPE(void extract_obj, (OBJ_DATA *));
+PROTOTYPE(void extract_char, (CHAR_DATA *, bool));
+PROTOTYPE(CHAR_DATA * get_char_room,
+		  (CHAR_DATA *, ROOM_INDEX_DATA *, const char *));
+PROTOTYPE(CHAR_DATA * get_char_world, (CHAR_DATA *, const char *));
+PROTOTYPE(OBJ_DATA * get_obj_type, (OBJ_INDEX_DATA *));
+PROTOTYPE(OBJ_DATA * get_obj_list, (CHAR_DATA *, const char *, OBJ_DATA *));
+PROTOTYPE(OBJ_DATA * get_obj_carry, (CHAR_DATA *, const char *, CHAR_DATA *));
+PROTOTYPE(OBJ_DATA * get_obj_wear, (CHAR_DATA *, const char *, bool));
+PROTOTYPE(OBJ_DATA * get_obj_here,
+		  (CHAR_DATA *, ROOM_INDEX_DATA *, const char *));
+PROTOTYPE(OBJ_DATA * get_obj_world, (CHAR_DATA *, const char *));
+PROTOTYPE(OBJ_DATA * create_money, (int, int));
+PROTOTYPE(int get_obj_number, (OBJ_DATA *));
+PROTOTYPE(int get_obj_weight, (OBJ_DATA *));
+PROTOTYPE(int get_true_weight, (OBJ_DATA *));
+PROTOTYPE(bool room_is_dark, (ROOM_INDEX_DATA *));
+PROTOTYPE(bool is_room_owner, (CHAR_DATA *, ROOM_INDEX_DATA *));
+PROTOTYPE(bool room_is_private, (ROOM_INDEX_DATA *));
+PROTOTYPE(bool can_see, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool can_see_obj, (CHAR_DATA *, OBJ_DATA *));
+PROTOTYPE(bool can_see_room, (CHAR_DATA *, ROOM_INDEX_DATA *));
+PROTOTYPE(bool can_drop_obj, (CHAR_DATA *, OBJ_DATA *));
+PROTOTYPE(bool is_friend, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool is_full_name, (const char *, const char *));
+PROTOTYPE(CHAR_DATA * get_char_id, (long));
 
 /* interp.c */
-void interpret args((CHAR_DATA * ch, const char *argument));
-bool is_number args((const char *arg));
-unsigned int number_argument args((const char *argument, char *arg));
-unsigned int mult_argument args((const char *argument, char *arg));
-const char *one_argument args((const char *argument, char *arg_first));
-void load_disabled args((void));
-void save_disabled args((void));
+PROTOTYPE(void interpret, (CHAR_DATA *, const char *));
+PROTOTYPE(bool is_number, (const char *));
+PROTOTYPE(unsigned int number_argument, (const char *, char *));
+PROTOTYPE(unsigned int mult_argument, (const char *, char *));
+PROTOTYPE(const char *one_argument, (const char *, char *));
+PROTOTYPE(void load_disabled, (void));
+PROTOTYPE(void save_disabled, (void));
 
 /* magic.c */
-int find_spell args((CHAR_DATA * ch, const char *name));
-int mana_cost(CHAR_DATA * ch, int min_mana, int level);
-int skill_lookup args((const char *name));
-bool saves_spell args((int level, CHAR_DATA * victim, int dam_type));
-void obj_cast_spell
-args((int sn, int level, CHAR_DATA * ch, CHAR_DATA * victim, OBJ_DATA * obj));
-bool check_dispel args((int dis_level, CHAR_DATA * victim, int sn));
-bool saves_dispel args((int dis_level, int spell_level, int duration));
+PROTOTYPE(int find_spell, (CHAR_DATA *, const char *));
+PROTOTYPE(int mana_cost, (CHAR_DATA *, int, int));
+PROTOTYPE(int skill_lookup, (const char *));
+PROTOTYPE(bool saves_spell, (int, CHAR_DATA *, int));
+PROTOTYPE(void obj_cast_spell,
+		  (int, int, CHAR_DATA *, CHAR_DATA *, OBJ_DATA *));
+PROTOTYPE(bool check_dispel, (int, CHAR_DATA *, int));
+PROTOTYPE(bool saves_dispel, (int, int, int));
 
 /* multiclass.c */
-bool can_use_skpell args((CHAR_DATA * ch, int sn));
-bool has_spells args((CHAR_DATA * ch));
-bool is_class args((CHAR_DATA * ch, int Class));
-bool is_same_class args((CHAR_DATA * ch, CHAR_DATA * victim));
-int number_classes args((CHAR_DATA * ch));
-char *class_long args((CHAR_DATA * ch));
-char *class_who args((CHAR_DATA * ch));
-char *class_short args((CHAR_DATA * ch));
-char *class_numbers args((CHAR_DATA * ch, bool pSave));
-int skill_level args((CHAR_DATA * ch, int sn));
-int skill_rating args((CHAR_DATA * ch, int sn));
-int group_rating args((CHAR_DATA * ch, int gn));
-bool check_base_group args((CHAR_DATA * ch, int gn));
-bool is_base_skill args((CHAR_DATA * ch, int sn));
-int get_hp_gain args((CHAR_DATA * ch));
-int get_mana_gain args((CHAR_DATA * ch));
-bool is_prime_stat args((CHAR_DATA * ch, int pStat));
-void add_default_groups args((CHAR_DATA * ch));
-void add_base_groups args((CHAR_DATA * ch));
-int get_stat_bonus args((CHAR_DATA * ch, int pStat));
-int get_thac00 args((CHAR_DATA * ch));
-int get_thac32 args((CHAR_DATA * ch));
-int get_hp_max args((CHAR_DATA * ch));
-int lvl_bonus args((CHAR_DATA * ch));
-int class_mult args((CHAR_DATA * ch));
-bool is_race_skill args((CHAR_DATA * ch, int sn));
-int hp_max args((CHAR_DATA * ch));
-int prime_class args((CHAR_DATA * ch));
+PROTOTYPE(bool can_use_skpell, (CHAR_DATA *, int));
+PROTOTYPE(bool has_spells, (CHAR_DATA *));
+PROTOTYPE(bool is_class, (CHAR_DATA *, int));
+PROTOTYPE(bool is_same_class, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(int number_classes, (CHAR_DATA *));
+PROTOTYPE(char *class_long, (CHAR_DATA *));
+PROTOTYPE(char *class_who, (CHAR_DATA *));
+PROTOTYPE(char *class_short, (CHAR_DATA *));
+PROTOTYPE(char *class_numbers, (CHAR_DATA *, bool));
+PROTOTYPE(int skill_level, (CHAR_DATA *, int));
+PROTOTYPE(int skill_rating, (CHAR_DATA *, int));
+PROTOTYPE(int group_rating, (CHAR_DATA *, int));
+PROTOTYPE(bool check_base_group, (CHAR_DATA *, int));
+PROTOTYPE(bool is_base_skill, (CHAR_DATA *, int));
+PROTOTYPE(int get_hp_gain, (CHAR_DATA *));
+PROTOTYPE(int get_mana_gain, (CHAR_DATA *));
+PROTOTYPE(bool is_prime_stat, (CHAR_DATA *, int));
+PROTOTYPE(void add_default_groups, (CHAR_DATA *));
+PROTOTYPE(void add_base_groups, (CHAR_DATA *));
+PROTOTYPE(int get_stat_bonus, (CHAR_DATA *, int));
+PROTOTYPE(int get_thac00, (CHAR_DATA *));
+PROTOTYPE(int get_thac32, (CHAR_DATA *));
+PROTOTYPE(int get_hp_max, (CHAR_DATA *));
+PROTOTYPE(int lvl_bonus, (CHAR_DATA *));
+PROTOTYPE(int class_mult, (CHAR_DATA *));
+PROTOTYPE(bool is_race_skill, (CHAR_DATA *, int));
+PROTOTYPE(int hp_max, (CHAR_DATA *));
+PROTOTYPE(int prime_class, (CHAR_DATA *));
 
 /* quest.c */
-bool chance args((int num));
-void do_mob_tell args((CHAR_DATA * ch, CHAR_DATA * victim, char *argument));
-void generate_quest args((CHAR_DATA * ch, CHAR_DATA * questman));
-void quest_update args((void));
-bool quest_level_diff args((CHAR_DATA * ch, CHAR_DATA * mob));
-void end_quest args((CHAR_DATA * ch, int time));
-OD *has_questobj args((CHAR_DATA * ch));
-void update_questobjs args((CHAR_DATA * ch, OBJ_DATA * obj));
-int qobj_cost args((OBJ_DATA * obj));
-int is_qobj args((OBJ_DATA * obj));
-void add_apply
-args((OBJ_DATA * obj, int loc, int mod, int where, int type, int dur,
-	  flag_t bit, int level));
-void do_mob_tell args((CHAR_DATA * ch, CHAR_DATA * victim, char *argument));
-void update_all_qobjs args((CHAR_DATA * ch));
-void unfinished_quest args((CHAR_DATA * ch));
+PROTOTYPE(bool chance, (int));
+PROTOTYPEF(void mob_tell, (CHAR_DATA *, CHAR_DATA *, const char *, ...), 3, 4);
+PROTOTYPE(void generate_quest, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void quest_update, (void));
+PROTOTYPE(bool quest_level_diff, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void end_quest, (CHAR_DATA *, int));
+PROTOTYPE(OBJ_DATA * has_questobj, (CHAR_DATA *));
+PROTOTYPE(void update_questobjs, (CHAR_DATA *, OBJ_DATA *));
+PROTOTYPE(int qobj_cost, (OBJ_DATA *));
+PROTOTYPE(int is_qobj, (OBJ_DATA *));
+PROTOTYPE(void add_apply,
+		  (OBJ_DATA *, apply_t, int, where_t, int, int, flag_t, int));
+PROTOTYPE(void update_all_qobjs, (CHAR_DATA *));
+PROTOTYPE(void unfinished_quest, (CHAR_DATA *));
 
 /* save.c */
-void save_char_obj args((CHAR_DATA * ch));
-bool load_char_obj args((DESCRIPTOR_DATA * d, const char *name));
-void update_corpses args((OBJ_DATA * obj, bool pdelete));
-void load_corpses args((void));
-void checkcorpse args((CHAR_DATA * ch));
+PROTOTYPE(void save_char_obj, (CHAR_DATA *));
+PROTOTYPE(bool load_char_obj, (DESCRIPTOR_DATA *, const char *));
+PROTOTYPE(void update_corpses, (OBJ_DATA *, bool));
+PROTOTYPE(void load_corpses, (void));
+PROTOTYPE(void checkcorpse, (CHAR_DATA *));
 
 /* skills.c */
-bool parse_gen_groups args((CHAR_DATA * ch, const char *argument));
-void list_group_costs args((CHAR_DATA * ch));
-void list_group_known args((CHAR_DATA * ch));
-int exp_per_level args((CHAR_DATA * ch, int points));
-void check_improve args((CHAR_DATA * ch, int sn, bool success, int multiplier));
-int group_lookup args((const char *name));
-void gn_add args((CHAR_DATA * ch, int gn));
-void gn_remove args((CHAR_DATA * ch, int gn));
-void group_add args((CHAR_DATA * ch, const char *name, bool deduct));
-void group_remove args((CHAR_DATA * ch, const char *name));
+PROTOTYPE(bool parse_gen_groups, (CHAR_DATA *, const char *));
+PROTOTYPE(void list_group_costs, (CHAR_DATA *));
+PROTOTYPE(void list_group_known, (CHAR_DATA *));
+PROTOTYPE(int exp_per_level, (CHAR_DATA *, int));
+PROTOTYPE(void check_improve, (CHAR_DATA *, int, bool, int));
+PROTOTYPE(int group_lookup, (const char *));
+PROTOTYPE(void gn_add, (CHAR_DATA *, int));
+PROTOTYPE(void gn_remove, (CHAR_DATA *, int));
+PROTOTYPE(void group_add, (CHAR_DATA *, const char *, bool));
+PROTOTYPE(void group_remove, (CHAR_DATA *, const char *));
 
 /* special.c */
-SF *spec_lookup args((const char *name));
-const char *spec_name args((SPEC_FUN * function));
+PROTOTYPE(SPEC_FUN * spec_lookup, (const char *));
+PROTOTYPE(const char *spec_name, (SPEC_FUN *));
 
 /* statlist.c */
-void update_statlist args((CHAR_DATA * ch, bool pdelete));
-void load_statlist args((void));
-void save_statlist args((void));
-void show_game_stats args((CHAR_DATA * ch, int type));
+PROTOTYPE(void update_statlist, (CHAR_DATA *, bool));
+PROTOTYPE(void show_game_stats, (CHAR_DATA *, int));
 
 /* teleport.c */
-RID *room_by_name args((char *target, int level, bool error));
+PROTOTYPE(ROOM_INDEX_DATA * room_by_name, (char *, int, bool));
 
 /* update.c */
-void advance_level args((CHAR_DATA * ch, bool hide));
-void gain_exp args((CHAR_DATA * ch, int gain));
-void gain_condition args((CHAR_DATA * ch, int iCond, int value));
-void update_handler args((void));
-
-/* social-edit.c */
-void load_social_table();
-void save_social_table();
+PROTOTYPE(void advance_level, (CHAR_DATA *, bool));
+PROTOTYPE(void gain_exp, (CHAR_DATA *, int));
+PROTOTYPE(void gain_condition, (CHAR_DATA *, int, int));
+PROTOTYPE(void update_handler, (void));
 
 /* string.c */
-void string_edit args((CHAR_DATA * ch, const char **pString));
-void string_append args((CHAR_DATA * ch, const char **pString));
-const char *string_replace args((const char *orig, char *old, char *pnew));
-void string_add args((CHAR_DATA * ch, char *argument));
-const char *format_string args((const char *oldstring /*, bool fSpace */ ));
-const char *first_arg args((const char *argument, char *arg_first, bool fCase));
-const char *string_unpad args((const char *argument));
-const char *string_proper args((const char *argument));
-int parse_string_command
-args((const char **text, const char *str, CHAR_DATA * ch));
-void parse_action
-args((const char **text, int command, const char *string, CHAR_DATA * ch));
+PROTOTYPE(void string_edit, (CHAR_DATA *, const char **));
+PROTOTYPE(void string_append, (CHAR_DATA *, const char **));
+PROTOTYPE(const char *string_replace, (const char *, char *old, char *));
+PROTOTYPE(void string_add, (CHAR_DATA *, char *));
+PROTOTYPE(const char *format_string, (const char *oldstring /*, bool */ ));
+PROTOTYPE(const char *first_arg, (const char *, char *, bool));
+PROTOTYPE(const char *string_unpad, (const char *));
+PROTOTYPE(const char *string_proper, (const char *));
+PROTOTYPE(strshow_t parse_string_command,
+		  (const char **, const char *, CHAR_DATA *));
+PROTOTYPE(void parse_action, (const char **, int, const char *, CHAR_DATA *));
 
 /* olc.c */
-bool run_olc_editor args((DESCRIPTOR_DATA * d, char *incomm));
-char *olc_ed_name args((CHAR_DATA * ch));
-char *olc_ed_vnum args((CHAR_DATA * ch));
-void clean_area_links args((AREA_DATA * target));
-bool vnum_OK args((vnum_t lnum, vnum_t hnum));
+PROTOTYPE(bool run_olc_editor, (DESCRIPTOR_DATA *, char *));
+PROTOTYPE(const char *olc_ed_name, (DESCRIPTOR_DATA *));
+PROTOTYPE(char *olc_ed_vnum, (DESCRIPTOR_DATA *));
+PROTOTYPE(void clean_area_links, (AREA_DATA *));
+PROTOTYPE(bool vnum_OK, (vnum_t, vnum_t));
 
 /* lookup.c */
-RACE_DATA *race_lookup args((const char *name));
-int item_lookup args((const char *name));
-int liq_lookup args((const char *name));
+PROTOTYPE(RACE_DATA * race_lookup, (const char *));
+PROTOTYPE(int item_lookup, (const char *));
+PROTOTYPE(int liq_lookup, (const char *));
 
 /* mccp.c */
 #if !defined(NO_MCCP)
-bool compressStart(DESCRIPTOR_DATA * desc);
-bool compressEnd(DESCRIPTOR_DATA * desc);
-bool processCompressed(DESCRIPTOR_DATA * desc);
-bool writeCompressed(DESCRIPTOR_DATA * desc, char *txt, int length);
+PROTOTYPE(bool compressStart, (DESCRIPTOR_DATA *, int));
+PROTOTYPE(bool compressEnd, (DESCRIPTOR_DATA *, int));
+PROTOTYPE(bool processCompressed, (DESCRIPTOR_DATA *));
+PROTOTYPE(bool writeCompressed, (DESCRIPTOR_DATA *, const char *, int));
 #endif
 
-void hunt_victim args((CHAR_DATA * ch));
-void announce args((CHAR_DATA * ch, flag_t bit, const char *message, ...))
-	__attribute__ ((format(printf, 3, 4)));
+PROTOTYPE(void hunt_victim, (CHAR_DATA *));
+PROTOTYPEF(void announce, (CHAR_DATA *, flag_t, const char *, ...), 3, 4);
 
 /* gquest.c */
-bool load_gquest_data args((void));
-bool save_gquest_data args((void));
-void auto_gquest args((void));
-bool start_gquest args((CHAR_DATA * ch, const char *argument));
-void end_gquest args((CHAR_DATA * who));
-void gquest_update args((void));
-bool generate_gquest args((CHAR_DATA * who));
-int count_gqmobs args((GQ_LIST * gql));
-int is_gqmob args((GQ_LIST * gql, vnum_t vnum));
-bool is_random_gqmob args((vnum_t vnum));
+PROTOTYPE(void auto_gquest, (void));
+PROTOTYPE(bool start_gquest, (CHAR_DATA *, const char *));
+PROTOTYPE(void end_gquest, (CHAR_DATA *));
+PROTOTYPE(void gquest_update, (void));
+PROTOTYPE(bool generate_gquest, (CHAR_DATA *));
+PROTOTYPE(int count_gqmobs, (GQ_DATA *));
+PROTOTYPE(int is_gqmob, (GQ_DATA *, vnum_t));
+PROTOTYPE(bool is_random_gqmob, (vnum_t));
 
 /*explored.c */
-void fread_rle args((char *explored, FILE * fp));
-void fwrite_rle args((char *explored, FILE * fp));
-int arearooms args((AREA_DATA * area));
-void update_explored args((CHAR_DATA * ch));
-int bitcount args((char ch));
-int roomcount args((CHAR_DATA * ch));
-int areacount args((CHAR_DATA * ch, AREA_DATA * area));
+PROTOTYPE(void fread_rle, (char *, FILE *));
+PROTOTYPE(void read_rle, (char *, READ_DATA *));
+PROTOTYPE(void fwrite_rle, (char *, FILE *));
+PROTOTYPE(int arearooms, (AREA_DATA *));
+PROTOTYPE(void update_explored, (CHAR_DATA *));
+PROTOTYPE(int bitcount, (char));
+PROTOTYPE(int roomcount, (CHAR_DATA *));
+PROTOTYPE(int areacount, (CHAR_DATA *, AREA_DATA *));
 
-bool emptystring args((const char *));
-void draw_map args((CHAR_DATA * ch, const char *desc));
+PROTOTYPE(bool emptystring, (const char *));
+PROTOTYPE(void draw_map, (CHAR_DATA *, const char *));
 
 /* war.c */
-void war_channel args((CHAR_DATA * ch, char *message));
-void war_update args((void));
-void auto_war args((void));
-void check_war args((CHAR_DATA * ch, CHAR_DATA * victim));
-bool is_safe_war args((CHAR_DATA * ch, CHAR_DATA * wch));
-void war_talk args((CHAR_DATA * ch, const char *argument));
-void end_war args((void));
-bool abort_race_war args((void));
-bool abort_class_war args((void));
-bool abort_clan_war args((void));
-void extract_war args((CHAR_DATA * ch));
-bool load_war_data args((void));
-bool save_war_data args((void));
-
-void save_clans args((void));
-void load_clans args((void));
-void load_commands args((void));
-void save_commands args((void));
-CMD_DATA *command_lookup args((const char *name));
-void save_skills args((void));
-void load_skills args((void));
-void save_groups args((void));
-void load_groups args((void));
-void save_races args((void));
-void load_races args((void));
-void save_classes args((void));
-void load_classes args((void));
-
-void delete_home args((CHAR_DATA * ch));
-int count_home args((CHAR_DATA * ch));
-
-void extract_auc args((CHAR_DATA * ch));
-AUCTION_DATA *auction_lookup args((int num));
-int get_auc_id args((void));
-bool has_auction args((CHAR_DATA * ch));
-void reset_auc args((AUCTION_DATA * auc, bool forced));
-int count_auc args((CHAR_DATA * ch));
-void auction_update args((void));
-long advatoi args((const char *s));
-
-const char *get_sector_color args((int sector));
-
-OBJ_DATA *get_donation_pit args((void));
-void fread_obj args((CHAR_DATA * ch, FILE * fp, bool pit));
-void fwrite_obj
-args((CHAR_DATA * ch, OBJ_DATA * obj, FILE * fp, int iNest, char *marker));
-void load_donation_pit args((void));
-void save_donation_pit args((void));
-
-void fread_char args((CHAR_DATA * ch, FILE * fp));
-void pload_default args((CHAR_DATA * ch));
-
-void check_arena args((CHAR_DATA * ch, CHAR_DATA * victim));
-void extract_arena args((CHAR_DATA * ch));
-bool IS_IN_ARENA args((CHAR_DATA * ch));
-
-char *prog_type_to_name args((flag_t type));
-void program_flow
-args((vnum_t vnum, const char *source, CHAR_DATA * mob, OBJ_DATA * obj,
-	  ROOM_INDEX_DATA * room, CHAR_DATA * ch, const void *arg1,
-	  const void *arg2));
-void p_act_trigger
-args((const char *argument, CHAR_DATA * mob, OBJ_DATA * obj,
-	  ROOM_INDEX_DATA * room, CHAR_DATA * ch, const void *arg1,
-	  const void *arg2, flag_t type));
-bool p_percent_trigger
-args((CHAR_DATA * mob, OBJ_DATA * obj, ROOM_INDEX_DATA * room,
-	  CHAR_DATA * ch, const void *arg1, const void *arg2, flag_t type));
-void p_bribe_trigger args((CHAR_DATA * mob, CHAR_DATA * ch, long amount));
-bool p_exit_trigger args((CHAR_DATA * ch, int dir, int type));
-void p_give_trigger
-args((CHAR_DATA * mob, OBJ_DATA * obj, ROOM_INDEX_DATA * room,
-	  CHAR_DATA * ch, OBJ_DATA * dropped, flag_t type));
-void p_greet_trigger args((CHAR_DATA * ch, int type));
-void p_hprct_trigger args((CHAR_DATA * mob, CHAR_DATA * ch));
-void mob_interpret args((CHAR_DATA * ch, const char *argument));
-void obj_interpret args((OBJ_DATA * obj, const char *argument));
-void room_interpret args((ROOM_INDEX_DATA * room, const char *argument));
-void do_obj args((OBJ_DATA * obj, const char *argument));
-void do_room args((ROOM_INDEX_DATA * room, const char *argument));
-
-bool is_deity_skill args((CHAR_DATA * ch, int sn));
-void load_deities args((void));
-void save_deities args((void));
-
-void update_webpasses args((CHAR_DATA * ch, bool pDelete));
-void save_webpasses args((void));
-void load_webpasses args((void));
-
-bool write_to_descriptor args((DESCRIPTOR_DATA * d, char *txt, int length));
-
-int check_buddy args((CHAR_DATA * ch, CHAR_DATA * fch));
-
-int srt_skills args((const void *p1, const void *p2));
-
-void add_help args((HELP_DATA * help));
-void add_area args((AREA_DATA * pArea));
-void unlink_area args((AREA_DATA * pArea));
-
-char *FORMATF args((const char *formatbuf, ...))
-	__attribute__ ((format(printf, 1, 2)));
-void *alloc_perm args((size_t sMem));
-
-void save_members args((void));
-void update_members args((CHAR_DATA * ch, bool pdelete));
-void load_members args((void));
-
-void unlink_command args((CMD_DATA * command));
-void add_command args((CMD_DATA * command));
-void unhash_command args((CMD_DATA * command));
-void hash_command args((CMD_DATA * command));
-
-void unlink_social args((SOCIAL_DATA * social));
-void add_social args((SOCIAL_DATA * social));
-void unhash_social args((SOCIAL_DATA * social));
-void hash_social args((SOCIAL_DATA * social));
-
-SOCIAL_DATA *find_social args((const char *command));
-
-void set_on_off
-args(
-	 (CHAR_DATA * ch, flag_t * flags, flag_t flag, const char *on,
-	  const char *off));
-void print_on_off
-args((CHAR_DATA * ch, bool is_set, const char *cmd, const char *desc));
-
-char *make_colour args((void));
-
-void set_vtimer args((long sec));
-char *str_time args((time_t timet, int tz, const char *format));
-
-int calc_max_level args((CHAR_DATA * ch));
-const char *high_level_name args((int level, bool fLong));
-
-#undef	CD
-#undef	MID
-#undef	OD
-#undef	OID
-#undef	RID
-#undef	SF
-#undef AD
+PROTOTYPE(void war_channel, (CHAR_DATA *, char *));
+PROTOTYPE(void war_update, (void));
+PROTOTYPE(void auto_war, (void));
+PROTOTYPE(void check_war, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(bool is_safe_war, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void war_talk, (CHAR_DATA *, const char *));
+PROTOTYPE(void end_war, (void));
+PROTOTYPE(bool abort_race_war, (void));
+PROTOTYPE(bool abort_class_war, (void));
+PROTOTYPE(bool abort_clan_war, (void));
+PROTOTYPE(void extract_war, (CHAR_DATA *));
+
+PROTOTYPE(CMD_DATA * command_lookup, (const char *));
+
+PROTOTYPE(void delete_home, (CHAR_DATA *));
+PROTOTYPE(int count_home, (CHAR_DATA *));
+
+PROTOTYPE(void extract_auc, (CHAR_DATA *));
+PROTOTYPE(AUCTION_DATA * auction_lookup, (int));
+PROTOTYPE(int get_auc_id, (void));
+PROTOTYPE(bool has_auction, (CHAR_DATA *));
+PROTOTYPE(void reset_auc, (AUCTION_DATA *, bool));
+PROTOTYPE(int count_auc, (CHAR_DATA *));
+PROTOTYPE(void auction_update, (void));
+PROTOTYPE(long advatoi, (const char *));
+
+PROTOTYPE(const char *get_sector_color, (sector_t));
+
+PROTOTYPE(OBJ_DATA * get_donation_pit, (void));
+PROTOTYPE(void read_obj, (CHAR_DATA *, READ_DATA *, bool));
+PROTOTYPE(void fwrite_obj, (CHAR_DATA *, OBJ_DATA *, FILE *, int, char *));
+PROTOTYPE(void load_donation_pit, (void));
+PROTOTYPE(void save_donation_pit, (void));
+
+PROTOTYPE(void read_char, (CHAR_DATA *, READ_DATA *));
+PROTOTYPE(void pload_default, (CHAR_DATA *));
+
+PROTOTYPE(void check_arena, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void extract_arena, (CHAR_DATA *));
+PROTOTYPE(bool IS_IN_ARENA, (CHAR_DATA *));
+
+PROTOTYPE(char *prog_type_to_name, (flag_t));
+PROTOTYPE(void program_flow, (vnum_t, const char *, CHAR_DATA *, OBJ_DATA *,
+							  ROOM_INDEX_DATA *, CHAR_DATA *, const void *arg1,
+							  const void *));
+PROTOTYPE(void p_act_trigger, (const char *, CHAR_DATA *, OBJ_DATA *,
+							   ROOM_INDEX_DATA *, CHAR_DATA *, const void *,
+							   const void *, flag_t));
+PROTOTYPE(bool p_percent_trigger, (CHAR_DATA *, OBJ_DATA *, ROOM_INDEX_DATA *,
+								   CHAR_DATA *, const void *, const void *,
+								   flag_t));
+PROTOTYPE(void p_bribe_trigger, (CHAR_DATA *, CHAR_DATA *, long));
+PROTOTYPE(bool p_exit_trigger, (CHAR_DATA *, int, prog_t));
+PROTOTYPE(void p_give_trigger, (CHAR_DATA *, OBJ_DATA *, ROOM_INDEX_DATA *,
+								CHAR_DATA *, OBJ_DATA *, flag_t));
+PROTOTYPE(void p_greet_trigger, (CHAR_DATA *, prog_t));
+PROTOTYPE(void p_hprct_trigger, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(void mob_interpret, (CHAR_DATA *, const char *));
+PROTOTYPE(void obj_interpret, (OBJ_DATA *, const char *));
+PROTOTYPE(void room_interpret, (ROOM_INDEX_DATA *, const char *));
+PROTOTYPE(void do_obj, (OBJ_DATA *, const char *));
+PROTOTYPE(void do_room, (ROOM_INDEX_DATA *, const char *));
+
+PROTOTYPE(bool is_deity_skill, (CHAR_DATA *, int));
+
+PROTOTYPE(void update_webpasses, (CHAR_DATA *, bool));
+
+PROTOTYPE(bool d_write, (DESCRIPTOR_DATA *, const char *, int));
+
+PROTOTYPE(int check_buddy, (CHAR_DATA *, CHAR_DATA *));
+
+PROTOTYPE(int srt_skills, (const void *, const void *));
+
+PROTOTYPE(void add_help, (HELP_DATA *));
+PROTOTYPE(void add_area, (AREA_DATA *));
+PROTOTYPE(void unlink_area, (AREA_DATA *));
+
+PROTOTYPEF(char *FORMATF, (const char *, ...), 1, 2);
+PROTOTYPE(void *alloc_perm, (size_t));
+
+PROTOTYPE(void update_members, (CHAR_DATA *, bool));
+
+PROTOTYPE(void unlink_command, (CMD_DATA *));
+PROTOTYPE(void add_command, (CMD_DATA *));
+PROTOTYPE(void unhash_command, (CMD_DATA *));
+PROTOTYPE(void hash_command, (CMD_DATA *));
+
+PROTOTYPE(void unlink_social, (SOCIAL_DATA *));
+PROTOTYPE(void add_social, (SOCIAL_DATA *));
+PROTOTYPE(void unhash_social, (SOCIAL_DATA *));
+PROTOTYPE(void hash_social, (SOCIAL_DATA *));
+
+PROTOTYPE(SOCIAL_DATA * find_social, (const char *));
+
+PROTOTYPE(void set_on_off, (CHAR_DATA *, flag_t *, flag_t, const char *,
+							const char *));
+PROTOTYPE(void print_on_off, (CHAR_DATA *, bool, const char *, const char *));
+
+PROTOTYPE(char *make_colour, (void));
+
+PROTOTYPE(char *str_time, (time_t, int, const char *));
+
+PROTOTYPE(int calc_max_level, (CHAR_DATA *));
+PROTOTYPE(const char *high_level_name, (int, bool));
+
+PROTOTYPE(void add_random_exit, (ROOM_INDEX_DATA *, RESET_DATA *, bool));
+PROTOTYPE(int get_direction, (const char *));
+PROTOTYPE(int reset_door, (RESET_DATA *, bool));
+
+PROTOTYPE(void crs_update, (void));
+PROTOTYPE(const char *format_pulse, (int));
+PROTOTYPE(const char *crs_sprintf, (bool, bool));
+PROTOTYPE(bool read_from_descriptor, (DESCRIPTOR_DATA *));
+
+PROTOTYPE(bool bust_a_portal, (CHAR_DATA *));
+PROTOTYPE(void portal_map, (CHAR_DATA *, ROOM_INDEX_DATA *));
+PROTOTYPE(void send_portal, (DESCRIPTOR_DATA *, const char *, ...));
+
+PROTOTYPE(void send_imp, (DESCRIPTOR_DATA *, char *));
+
+PROTOTYPE(void image_to_char, (CHAR_DATA *, const char *));
+PROTOTYPE(void send_sound, (CHAR_DATA *, const char *, int));
+PROTOTYPE(void send_music, (CHAR_DATA *, const char *, const char *));
+
+PROTOTYPE(unsigned int get_line, (char *, unsigned int));
+PROTOTYPE(void reformat_desc, (char *));
+
+#if defined(__cplusplus)
+#define dwrap(d, buf) (d)->wrap((buf))
+#else
+PROTOTYPE(void dwrap, (DESCRIPTOR_DATA *, const char *));
+#endif
+PROTOTYPE(void dwrapln, (DESCRIPTOR_DATA *, const char *));
+PROTOTYPEF(void dwrapf, (DESCRIPTOR_DATA *, const char *, ...), 2, 3);
+PROTOTYPEF(void dwraplnf, (DESCRIPTOR_DATA *, const char *, ...), 2, 3);
+
+PROTOTYPE(char *fix_string, (const char *));
+
+PROTOTYPE(void autodrop, (CHAR_DATA *));
+PROTOTYPE(bool can_bypass, (CHAR_DATA *, CHAR_DATA *));
+PROTOTYPE(long dambonus, (CHAR_DATA *, CHAR_DATA *, long, int));
+PROTOTYPE(bool can_counter, (CHAR_DATA *));
+PROTOTYPE(void improve_stance, (CHAR_DATA *));
+PROTOTYPE(char *get_stance_name, (int));
+
+PROTOTYPE(bool is_ignoring, (CHAR_DATA *, const char *, flag_t));
+PROTOTYPE(void write_time, (void));
+PROTOTYPE(void log_error, (const char *));
+
+PROTOTYPE(void finish_note, (BOARD_DATA *, NOTE_DATA *));	/* attach a note to a board */
+PROTOTYPE(void free_note, (NOTE_DATA *));	/* deallocate memory used by a note */
+PROTOTYPE(void load_boards, (void));	/* load all boards */
+PROTOTYPE(int board_lookup, (const char *));	/* Find a board with that name */
+PROTOTYPE(bool is_note_to, (CHAR_DATA *, NOTE_DATA *));	/* is tha note to ch? */
+PROTOTYPE(void personal_message, (const char *, const char *,
+								  const char *, const int, const char *));
+PROTOTYPE(void make_note, (const char *, const char *, const char *,
+						   const char *, const int, const char *));
+PROTOTYPE(void save_notes, (void));
+
+/* for nanny */
+PROTOTYPE(void handle_con_note_to, (DESCRIPTOR_DATA *, const char *));
+PROTOTYPE(void handle_con_note_subject, (DESCRIPTOR_DATA *, const char *));
+PROTOTYPE(void handle_con_note_expire, (DESCRIPTOR_DATA *, const char *));
+PROTOTYPE(void handle_con_note_text, (DESCRIPTOR_DATA *, const char *));
+PROTOTYPE(void handle_con_note_finish, (DESCRIPTOR_DATA *, const char *));
+
+PROTOTYPE(long fread_long, (FILE *));
+PROTOTYPE(long read_long, (READ_DATA *));
+
+PROTOTYPE(char *timestr, (time_t, bool));
+
+PROTOTYPE(int get_scr_cols, (CHAR_DATA *));
+PROTOTYPE(int get_scr_lines, (CHAR_DATA *));
+PROTOTYPEF(bool file_exists, (const char *,...), 1, 2);
+
+#endif
diff -ur -x config -x o -x rom src/quest.c new/quest.c
--- src/quest.c	Tue May 27 02:46:36 2003
+++ new/quest.c	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /****************************************************************************
@@ -36,17 +36,6 @@
 *  the latest version of quest.c, please send a request to the above add-   *
 *  ress. Quest Code v2.03. Please do not remove this notice from this file. *
 ****************************************************************************/
-
-/****************************************************************************
- * Updated Quest Code copyright 1999-2001                                   *
- * Markanth : dlmud@dlmud.com                                               *
- * Devil's Lament : dlmud.com port 3778                                     *
- * Web Page : http://www.dlmud.com                                          *
- ***************************************************************************/
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 #include "merc.h"
 #include "magic.h"
 #include "interp.h"
@@ -67,18 +56,18 @@
 const struct quest_type quest_table[] = {
 /*name *//*short description *//*vnum *//*cost */
 	{"nohunger", "No Hunger/Thirst (quest buy nohunger)", 0, 3000},
-	{"aura", "Aura of Sanctuary", QUEST_AURA, 2600},
-	{"sword", "Sword of the Ancients", QUEST_SWORD, 2500},
-	{"breastplate", "BreastPlate of the Ancients", QUEST_BPLATE, 2500},
-	{"boots", "Boots of the Ancients", QUEST_BOOTS, 2500},
-	{"gloves", "Gloves of Protection", QUEST_GLOVES, 2500},
-	{"flame", "Flame of the Ancients", QUEST_FLAME, 2500},
-	{"helm", "Helm of True Sight", QUEST_HELM, 2300},
-	{"bag", "Bag of the Ancients", QUEST_BAG, 1000},
-	{"shield", "Shield of the Ancients", QUEST_SHIELD, 750},
-	{"regeneration", "Ring of Regeneration", QUEST_REGEN, 700},
-	{"invisibility", "Ring of Invisibility", QUEST_INVIS, 500},
-	{"trivia", "Trivia Pill", QUEST_TRIVIA, 100},
+	{"aura", NULL, QUEST_AURA, 2600},
+	{"sword", NULL, QUEST_SWORD, 2500},
+	{"breastplate", NULL, QUEST_BPLATE, 2500},
+	{"boots", NULL, QUEST_BOOTS, 2500},
+	{"gloves", NULL, QUEST_GLOVES, 2500},
+	{"flame", NULL, QUEST_FLAME, 2500},
+	{"helm", NULL, QUEST_HELM, 2300},
+	{"bag", NULL, QUEST_BAG, 1000},
+	{"shield", NULL, QUEST_SHIELD, 750},
+	{"regeneration", NULL, QUEST_REGEN, 700},
+	{"invisibility", NULL, QUEST_INVIS, 500},
+	{"trivia", NULL, QUEST_TRIVIA, 100},
 	{NULL, NULL, 0, 0}
 };
 
@@ -127,7 +116,7 @@
 		if (obj->pIndexData->vnum == quest_table[i].vnum)
 			return quest_table[i].cost;
 	}
-	return 0;
+	return obj->cost;
 }
 
 /*
@@ -156,7 +145,7 @@
 	return;
 }
 
-void add_apply(OBJ_DATA * obj, int loc, int mod, int where, int type,
+void add_apply(OBJ_DATA * obj, apply_t loc, int mod, where_t where, int type,
 			   int dur, flag_t bit, int level)
 {
 	AFFECT_DATA pAf;
@@ -184,12 +173,12 @@
 
 	if (obj == NULL || obj->pIndexData == NULL)
 	{
-		bug("update_questobjs: NULL obj", 0);
+		bug("update_questobjs: NULL obj");
 		return;
 	}
 	if (ch == NULL)
 	{
-		bug("update_questobjs: NULL ch", 0);
+		bug("update_questobjs: NULL ch");
 		return;
 	}
 
@@ -267,7 +256,7 @@
 void update_all_qobjs(CHAR_DATA * ch)
 {
 	OBJ_DATA *obj;
-	int iWear;
+	wloc_t iWear;
 
 	for (obj = ch->first_carrying; obj != NULL; obj = obj->next_content)
 	{
@@ -364,7 +353,7 @@
 
 	if (ch->pcdata->questloc <= 0)
 	{
-		bug("QUEST INFO: ch->questloc = %d", ch->pcdata->questloc);
+		bugf("QUEST INFO: ch->questloc = %ld", ch->pcdata->questloc);
 		return;
 	}
 	if (ch->in_room == NULL)
@@ -373,12 +362,12 @@
 	room = get_room_index(ch->pcdata->questloc);
 	if (room->area == NULL)
 	{
-		bug("QUEST INFO: room(%d)->area == NULL", ch->pcdata->questloc);
+		bugf("QUEST INFO: room(%ld)->area == NULL", ch->pcdata->questloc);
 		return;
 	}
 	if (room->area->name == NULL)
 	{
-		bug("QUEST INFO: area->name == NULL", 0);
+		bug("QUEST INFO: area->name == NULL");
 		return;
 	}
 	chprintlnf(ch,
@@ -386,7 +375,7 @@
 			   what, room->area->name);
 	if (room->name == NULL)
 	{
-		bug("QUEST INFO: room(%d)->name == NULL", ch->pcdata->questloc);
+		bugf("QUEST INFO: room(%ld)->name == NULL", ch->pcdata->questloc);
 		return;
 	}
 	chprintlnf(ch, "near %s.", room->name);
@@ -432,7 +421,7 @@
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		quest_usage(ch);
 		return;
@@ -536,7 +525,7 @@
 			}
 		}
 
-		bug("QUEST INFO: Questor with no kill, mob or obj", 0);
+		bugf("QUEST INFO: Questor with no kill, mob or obj");
 		end_quest(ch, QUEST_TIME / 4);
 		return;
 	}
@@ -550,7 +539,7 @@
 			return;
 		}
 
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			chprintln(ch, "Syntax: quest reset <player>");
 			return;
@@ -613,13 +602,17 @@
 
 	if (!str_cmp(arg1, "list"))
 	{
+		OBJ_INDEX_DATA *test;
 		act("$n asks $N for a list of quest items.", ch, NULL, questman,
 			TO_ROOM);
 		chprintln(ch, "\tCurrent Quest Items available for Purchase:");
-		for (i = 0; quest_table[i].descr != NULL; i++)
+		for (i = 0; quest_table[i].name != NULL; i++)
 		{
+			test = get_obj_index(quest_table[i].vnum);
 			chprintlnf(ch, "\t%-4dqp ........ %s",
-					   quest_table[i].cost, quest_table[i].descr);
+					   quest_table[i].cost,
+					   test ? test->short_descr : quest_table[i].descr !=
+					   NULL ? quest_table[i].descr : "Unavailable");
 		}
 		chprintln(ch, "\tTo buy an item, type 'QUEST BUY <item>'.");
 		chprintln(ch, "\tFor more info on quest items type 'help questitems'");
@@ -629,7 +622,7 @@
 	else if (!str_cmp(arg1, "buy"))
 	{
 
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			chprintln(ch, "To buy an item, type 'QUEST BUY <item>'.");
 			return;
@@ -680,22 +673,20 @@
 				}
 				else
 				{
-					sprintf(buf,
-							"Sorry, %s, but you need %d quest points for that.",
-							ch->name, quest_table[i].cost);
-					do_mob_tell(ch, questman, buf);
+					mob_tell(ch, questman,
+							 "Sorry, %s, but you need %d quest points for that.",
+							 ch->name, quest_table[i].cost);
 					return;
 				}
 			}
 		}
-		sprintf(buf, "I don't have that item, %s.", ch->name);
-		do_mob_tell(ch, questman, buf);
+		mob_tell(ch, questman, "I don't have that item, %s.", ch->name);
 		return;
 	}
 
 	else if (!str_cmp(arg1, "sell"))
 	{
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			chprintln(ch, "To sell an item, type 'QUEST SELL <item>'.");
 			return;
@@ -708,8 +699,7 @@
 
 		if (!IS_OBJ_STAT(obj, ITEM_QUEST))
 		{
-			sprintf(buf, "That is not a quest item, %s.", ch->name);
-			do_mob_tell(ch, questman, buf);
+			mob_tell(ch, questman, "That is not a quest item, %s.", ch->name);
 			return;
 		}
 
@@ -730,14 +720,13 @@
 				return;
 			}
 		}
-		sprintf(buf, "I only take items I sell, %s.", ch->name);
-		do_mob_tell(ch, questman, buf);
+		mob_tell(ch, questman, "I only take items I sell, %s.", ch->name);
 		return;
 	}
 	else if (!str_cmp(arg1, "identify"))
 	{
 
-		if (arg2[0] == '\0')
+		if (IS_NULLSTR(arg2))
 		{
 			chprintln(ch, "To identify an item, type 'QUEST IDENTIFY <item>'.");
 			return;
@@ -777,8 +766,7 @@
 				}
 			}
 		}
-		sprintf(buf, "I don't have that item, %s.", ch->name);
-		do_mob_tell(ch, questman, buf);
+		mob_tell(ch, questman, "I don't have that item, %s.", ch->name);
 		return;
 	}
 
@@ -788,21 +776,19 @@
 		act("You ask $N for a quest.", ch, NULL, questman, TO_CHAR);
 		if (IS_SET(ch->act, PLR_QUESTOR))
 		{
-			do_mob_tell(ch, questman, "But you're already on a quest!");
+			mob_tell(ch, questman, "But you're already on a quest!");
 			return;
 		}
 		if (ch->pcdata->nextquest > 0)
 		{
-			sprintf(buf,
-					"You're very brave, %s, but let someone else have a chance.",
-					ch->name);
-			do_mob_tell(ch, questman, buf);
-			do_mob_tell(ch, questman, "Come back later.");
+			mob_tell(ch, questman,
+					 "You're very brave, %s, but let someone else have a chance.",
+					 ch->name);
+			mob_tell(ch, questman, "Come back later.");
 			return;
 		}
 
-		sprintf(buf, "Thank you, brave %s!", ch->name);
-		do_mob_tell(ch, questman, buf);
+		mob_tell(ch, questman, "Thank you, brave %s!", ch->name);
 		ch->pcdata->questmob = 0;
 		ch->pcdata->questobj = 0;
 
@@ -813,8 +799,8 @@
 	{
 		if (ch->pcdata->questgiver != questman->pIndexData->vnum)
 		{
-			do_mob_tell(ch, questman,
-						"I never sent you on a quest! Perhaps you're thinking of someone else.");
+			mob_tell(ch, questman,
+					 "I never sent you on a quest! Perhaps you're thinking of someone else.");
 			return;
 		}
 
@@ -831,13 +817,12 @@
 				act("You inform $N you have completed $s quest.",
 					ch, NULL, questman, TO_CHAR);
 
-				do_mob_tell(ch, questman,
-							"Congratulations on completing your quest!");
+				mob_tell(ch, questman,
+						 "Congratulations on completing your quest!");
 
-				sprintf(buf,
-						"As a reward, I am giving you %d quest points, and %d gold.",
-						points, reward);
-				do_mob_tell(ch, questman, buf);
+				mob_tell(ch, questman,
+						 "As a reward, I am giving you %d quest points, and %d gold.",
+						 points, reward);
 				if (chance(points / 5))
 				{
 					chprintln(ch, "You gain an extra Trivia Point!");
@@ -863,12 +848,11 @@
 					act("You hand $p to $N.", ch, obj, questman, TO_CHAR);
 					act("$n hands $p to $N.", ch, obj, questman, TO_ROOM);
 
-					do_mob_tell(ch, questman,
-								"Congratulations on completing your quest!");
-					sprintf(buf,
-							"As a reward, I am giving you %d quest points, and %d gold.",
-							points, reward);
-					do_mob_tell(ch, questman, buf);
+					mob_tell(ch, questman,
+							 "Congratulations on completing your quest!");
+					mob_tell(ch, questman,
+							 "As a reward, I am giving you %d quest points, and %d gold.",
+							 points, reward);
 					if (chance(points / 5))
 					{
 						chprintln(ch, "You gain an extra Trivia Point!");
@@ -883,8 +867,8 @@
 				}
 				else
 				{
-					do_mob_tell(ch, questman,
-								"You haven't completed the quest yet, but there is still time!");
+					mob_tell(ch, questman,
+							 "You haven't completed the quest yet, but there is still time!");
 					return;
 				}
 				return;
@@ -892,16 +876,17 @@
 			else if ((ch->pcdata->questmob > 0
 					  || ch->pcdata->questobj > 0) && ch->pcdata->countdown > 0)
 			{
-				do_mob_tell(ch, questman,
-							"You haven't completed the quest yet, but there is still time!");
+				mob_tell(ch, questman,
+						 "You haven't completed the quest yet, but there is still time!");
 				return;
 			}
 		}
 		if (ch->pcdata->nextquest > 0)
-			sprintf(buf, "But you didn't complete your quest in time!");
+			mob_tell(ch, questman,
+					 "But you didn't complete your quest in time!");
 		else
-			sprintf(buf, "You have to REQUEST a quest first, %s.", ch->name);
-		do_mob_tell(ch, questman, buf);
+			mob_tell(ch, questman, "You have to REQUEST a quest first, %s.",
+					 ch->name);
 		return;
 	}
 
@@ -913,16 +898,16 @@
 			questman, TO_CHAR);
 		if (ch->pcdata->questgiver != questman->pIndexData->vnum)
 		{
-			do_mob_tell(ch, questman,
-						"I never sent you on a quest! Perhaps you're thinking of someone else.");
+			mob_tell(ch, questman,
+					 "I never sent you on a quest! Perhaps you're thinking of someone else.");
 			return;
 		}
 
 		if (IS_SET(ch->act, PLR_QUESTOR))
 		{
 			end_quest(ch, QUEST_TIME - 2);
-			do_mob_tell(ch, questman,
-						"Your quest is over, but for your cowardly behavior, you may not quest again for 15 minutes.");
+			mob_tell(ch, questman,
+					 "Your quest is over, but for your cowardly behavior, you may not quest again for 15 minutes.");
 			return;
 		}
 		else
@@ -945,7 +930,6 @@
 	CHAR_DATA **mobs;
 	int mob_count;
 	OBJ_DATA *questitem = NULL;
-	char buf[MAX_STRING_LENGTH];
 	int mrange;
 
 	/*
@@ -984,9 +968,9 @@
 
 	if (mob_count == 0)			/* not likely but just in case */
 	{
-		do_mob_tell(ch, questman,
-					"I'm sorry, but I don't have any quests for you at this time.");
-		do_mob_tell(ch, questman, "Try again later.");
+		mob_tell(ch, questman,
+				 "I'm sorry, but I don't have any quests for you at this time.");
+		mob_tell(ch, questman, "Try again later.");
 		end_quest(ch, QUEST_TIME / 10);
 		free_mem(mobs);
 		return;
@@ -1035,8 +1019,7 @@
 		questitem = create_object(get_obj_index(objvnum), ch->level);
 		obj_to_room(questitem, room);
 		REMOVE_BIT(ch->act, PLR_CANLOOT);
-		free_string(questitem->owner);
-		questitem->owner = str_dup(ch->name);
+		replace_string(questitem->owner, ch->name);
 		questitem->cost = 0;
 		questitem->timer = (4 * ch->pcdata->countdown + 10) / 3;
 		ch->pcdata->questobj = questitem->pIndexData->vnum;
@@ -1045,32 +1028,28 @@
 		{
 		default:
 		case 0:
-			sprintf(buf,
-					"Vile pilferers have stolen %s from the royal treasury!",
-					questitem->short_descr);
-			do_mob_tell(ch, questman, buf);
-			do_mob_tell(ch, questman,
-						"My court wizardess, with her magic mirror, has pinpointed its location.");
+			mob_tell(ch, questman,
+					 "Vile pilferers have stolen %s from the royal treasury!",
+					 questitem->short_descr);
+			mob_tell(ch, questman,
+					 "My court wizardess, with her magic mirror, has pinpointed its location.");
 			break;
 		case 1:
-			sprintf(buf,
-					"A powerful wizard has stolen %s for his personal power!",
-					questitem->short_descr);
-			do_mob_tell(ch, questman, buf);
+			mob_tell(ch, questman,
+					 "A powerful wizard has stolen %s for his personal power!",
+					 questitem->short_descr);
 			break;
 		}
 
 		if (room->name != NULL)
 		{
-			sprintf(buf,
-					"Look for %s somewhere in the vicinity of %s!",
-					questitem->short_descr, room->name);
-			do_mob_tell(ch, questman, buf);
-
-			sprintf(buf,
-					"That location is in the general area of %s.",
-					room->area->name);
-			do_mob_tell(ch, questman, buf);
+			mob_tell(ch, questman,
+					 "Look for %s somewhere in the vicinity of %s!",
+					 questitem->short_descr, room->name);
+
+			mob_tell(ch, questman,
+					 "That location is in the general area of %s.",
+					 room->area->name);
 		}
 	}
 
@@ -1084,71 +1063,61 @@
 		{
 		default:
 		case 0:
-			sprintf(buf,
-					"An enemy of mine, %s, is making vile threats against the crown.",
-					victim->short_descr);
-			do_mob_tell(ch, questman, buf);
-			do_mob_tell(ch, questman, "This threat must be eliminated!");
+			mob_tell(ch, questman,
+					 "An enemy of mine, %s, is making vile threats against the crown.",
+					 victim->short_descr);
+			mob_tell(ch, questman, "This threat must be eliminated!");
 			break;
 
 		case 1:
-			sprintf(buf,
-					"Thera's most heinous criminal, %s, has escaped from the dungeon!",
-					victim->short_descr);
-			do_mob_tell(ch, questman, buf);
-			sprintf(buf,
-					"Since the escape, %s has murdered %d civillians!",
-					victim->short_descr, number_range(2, 20));
-			do_mob_tell(ch, questman, buf);
-			do_mob_tell(ch, questman,
-						"The penalty for this crime is death, and you are to deliver the sentence!");
+			mob_tell(ch, questman,
+					 "Thera's most heinous criminal, %s, has escaped from the dungeon!",
+					 victim->short_descr);
+			mob_tell(ch, questman,
+					 "Since the escape, %s has murdered %d civillians!",
+					 victim->short_descr, number_range(2, 20));
+			mob_tell(ch, questman,
+					 "The penalty for this crime is death, and you are to deliver the sentence!");
 			break;
 
 		case 2:
-			sprintf(buf,
-					"The Mayor of Midgaard has recently been attacked by %s.  This is an act of war!",
-					victim->short_descr);
-			do_mob_tell(ch, questman, buf);
-			sprintf(buf,
-					"%s must be severly dealt with for this injustice.",
-					victim->short_descr);
-			do_mob_tell(ch, questman, buf);
+			mob_tell(ch, questman,
+					 "The Mayor of Midgaard has recently been attacked by %s.  This is an act of war!",
+					 victim->short_descr);
+			mob_tell(ch, questman,
+					 "%s must be severly dealt with for this injustice.",
+					 victim->short_descr);
 			break;
 
 		case 3:
-			sprintf(buf,
-					"%s has been stealing valuables from the citizens of Arkham.",
-					victim->short_descr);
-			do_mob_tell(ch, questman, buf);
-			sprintf(buf,
-					"Make sure that %s never has the chance to steal again.",
-					victim->short_descr);
-			do_mob_tell(ch, questman, buf);
+			mob_tell(ch, questman,
+					 "%s has been stealing valuables from the citizens of Arkham.",
+					 victim->short_descr);
+			mob_tell(ch, questman,
+					 "Make sure that %s never has the chance to steal again.",
+					 victim->short_descr);
 			break;
 
 		}
 
 		if (room->name != NULL)
 		{
-			sprintf(buf,
-					"Seek %s out somewhere in the vicinity of %s!",
-					victim->short_descr, room->name);
-			do_mob_tell(ch, questman, buf);
-
-			sprintf(buf,
-					"That location is in the general area of %s.",
-					room->area->name);
-			do_mob_tell(ch, questman, buf);
+			mob_tell(ch, questman,
+					 "Seek %s out somewhere in the vicinity of %s!",
+					 victim->short_descr, room->name);
+
+			mob_tell(ch, questman,
+					 "That location is in the general area of %s.",
+					 room->area->name);
 		}
 		ch->pcdata->questmob = victim->pIndexData->vnum;
 	}
 	if (ch->pcdata->questmob > 0 || ch->pcdata->questobj > 0)
 	{
 		SET_BIT(ch->act, PLR_QUESTOR);
-		sprintf(buf, "You have %d minutes to complete this quest.",
-				ch->pcdata->countdown);
-		do_mob_tell(ch, questman, buf);
-		do_mob_tell(ch, questman, "May the gods go with you!");
+		mob_tell(ch, questman, "You have %d minutes to complete this quest.",
+				 ch->pcdata->countdown);
+		mob_tell(ch, questman, "May the gods go with you!");
 	}
 	else
 		end_quest(ch, QUEST_TIME / 10);
@@ -1158,7 +1127,7 @@
 
 bool quest_level_diff(CHAR_DATA * ch, CHAR_DATA * mob)
 {
-	int bonus = 20;				/* can modify this */
+	int bonus = 10 + lvl_bonus(ch);	/* can modify this */
 
 	if (IS_IMMORTAL(ch))
 		return TRUE;
@@ -1222,13 +1191,21 @@
 }
 
 /* handy dandy, victim must be an NPC */
-void do_mob_tell(CHAR_DATA * ch, CHAR_DATA * victim, char *argument)
+void mob_tell(CHAR_DATA * ch, CHAR_DATA * victim, const char *argument, ...)
 {
+	char buf[MSL];
+	va_list args;
 
-	if (!victim)
+	if (!victim || IS_NULLSTR(argument))
 		return;
 
-	chprintlnf(ch, "%s tells you '%s'", victim->short_descr, argument);
+	va_start(args, argument);
+	vsnprintf(buf, sizeof(buf), argument, args);
+	va_end(args);
+
+	chprintlnf(ch, "" CTAG(_TELLS1) "%s " CTAG(_TELLS1) "tells you '"
+			   CTAG(_TELLS2) "%s" CTAG(_TELLS1) "'{x",
+			   IS_NPC(victim) ? victim->short_descr : victim->name, buf);
 	return;
 }
 
@@ -1246,7 +1223,7 @@
 	if (!ch || IS_NPC(ch))
 		return;
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		chprintln(ch, "Syntax: Tpspend <item>");
 		chprintln(ch, "        Tpspend list");
@@ -1322,7 +1299,7 @@
 		{
 			ROOM_INDEX_DATA *oldroom;
 
-			if (arg2[0] == '\0')
+			if (IS_NULLSTR(arg2))
 			{
 				chprintln(ch,
 						  "Transfer you where? [recall/room name/character name]");
@@ -1384,10 +1361,9 @@
 		}
 		else
 		{
-			sprintf(buf,
-					"Sorry, %s, but you don't have enough trivia points for that.",
-					ch->name);
-			do_mob_tell(ch, triviamob, buf);
+			mob_tell(ch, triviamob,
+					 "Sorry, %s, but you don't have enough trivia points for that.",
+					 ch->name);
 			return;
 		}
 	}
@@ -1405,10 +1381,9 @@
 		}
 		else
 		{
-			sprintf(buf,
-					"Sorry, %s, but you don't have enough trivia points for that.",
-					ch->name);
-			do_mob_tell(ch, triviamob, buf);
+			mob_tell(ch, triviamob,
+					 "Sorry, %s, but you don't have enough trivia points for that.",
+					 ch->name);
 			return;
 		}
 	}
@@ -1424,10 +1399,9 @@
 		}
 		else
 		{
-			sprintf(buf,
-					"Sorry, %s, but you don't have enough trivia points for that.",
-					ch->name);
-			do_mob_tell(ch, triviamob, buf);
+			mob_tell(ch, triviamob,
+					 "Sorry, %s, but you don't have enough trivia points for that.",
+					 ch->name);
 			return;
 		}
 	}
@@ -1448,19 +1422,18 @@
 			}
 			else
 			{
-				sprintf(buf,
-						"I don't any more trivia pills to give, %s.", ch->name);
-				do_mob_tell(ch, triviamob, buf);
+				mob_tell(ch, triviamob,
+						 "I don't any more trivia pills to give, %s.",
+						 ch->name);
 			}
 			return;
 		}
 
 		else
 		{
-			sprintf(buf,
-					"Sorry, %s, but you don't have enough trivia points for that.",
-					ch->name);
-			do_mob_tell(ch, triviamob, buf);
+			mob_tell(ch, triviamob,
+					 "Sorry, %s, but you don't have enough trivia points for that.",
+					 ch->name);
 			return;
 		}
 	}
@@ -1477,10 +1450,9 @@
 		}
 		else
 		{
-			sprintf(buf,
-					"Sorry, %s, but you don't have enough trivia points for that.",
-					ch->name);
-			do_mob_tell(ch, triviamob, buf);
+			mob_tell(ch, triviamob,
+					 "Sorry, %s, but you don't have enough trivia points for that.",
+					 ch->name);
 			return;
 		}
 	}
@@ -1499,7 +1471,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (argument[0] == '\0' || !is_number(arg))
+	if (IS_NULLSTR(argument) || !is_number(arg))
 	{
 		chprintln(ch, "Syntax: qpgive [amount] [person]");
 		return;
@@ -1559,7 +1531,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (argument[0] == '\0' || !is_number(arg))
+	if (IS_NULLSTR(argument) || !is_number(arg))
 	{
 		chprintln(ch, "Syntax: tpgive [amount] [person]");
 		return;
diff -ur -x config -x o -x rom src/recycle.c new/recycle.c
--- src/recycle.c	Tue May 27 02:46:36 2003
+++ new/recycle.c	Sun Aug 31 19:23:21 2003
@@ -22,23 +22,19 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "recycle.h"
 #include "olc.h"
 #include "tables.h"
 #include "interp.h"
 
+PROTOTYPE(void free_channel_history, (PC_DATA *));
+PROTOTYPE(void init_channel_history, (PC_DATA *));
+
 /* stuff for recycling ban structures */
 BAN_DATA *ban_free;
 
@@ -83,9 +79,22 @@
 	d->run_buf = NULL;
 	d->run_head = NULL;
 	d->outsize = 2000;
-	d->scr_width = 80;
-	d->scr_height = 25;
+	d->scr_width = DEFAULT_SCR_WIDTH;
+	d->scr_height = DEFAULT_SCR_HEIGHT;
+	d->bytes_normal = 0;
+#if !defined(NO_MCCP)
+	d->bytes_compressed = 0;
+	d->mccp_version = 0;
+#endif
+	d->editor = ED_NONE;
+	d->pEdit = NULL;
 	alloc_mem(d->outbuf, char, d->outsize);
+	d->mxp.supports = &str_empty[0];
+	d->mxp.mxp_ver = 0.0;
+	d->mxp.client_ver = 0.0;
+	d->mxp.style_ver = 0.0;
+	d->mxp.client = &str_empty[0];
+
 	return d;
 }
 
@@ -97,6 +106,8 @@
 	free_string(d->host);
 	free_string(d->showstr_head);
 	free_mem(d->outbuf);
+	free_string(d->mxp.supports);
+	free_string(d->mxp.client);
 	INVALIDATE(d);
 	PUT_FREE(d, next, descriptor_free);
 }
@@ -247,7 +258,8 @@
 	ch->prompt = &str_empty[0];
 	ch->prefix = &str_empty[0];
 	ch->logon = current_time;
-	ch->lines = PAGELEN;
+	ch->lines = 0;
+	ch->columns = 0;
 	ch->clan = NULL;
 	ch->invited = NULL;
 	ch->rank = 0;
@@ -266,7 +278,8 @@
 		ch->perm_stat[i] = 13;
 		ch->mod_stat[i] = 0;
 	}
-
+	for (i = 0; i < MAX_STANCE; i++)
+		ch->stance[i] = 0;
 	return ch;
 }
 
@@ -309,36 +322,9 @@
 	return;
 }
 
-void clear_history(PC_DATA * pcdata)
-{
-	int i;
-	int x;
-
-	for (i = 0; i < LAST_MAX; i++)
-	{
-		for (x = 0; x < LAST_PAGE_LENGTH; x++)
-		{
-			pcdata->history[i][x] = &str_empty[0];
-		}
-	}
-}
-
-void free_history(PC_DATA * pcdata)
-{
-	int i, x;
-
-	for (i = 0; i < LAST_MAX; i++)
-	{
-		for (x = 0; x < LAST_PAGE_LENGTH; x++)
-		{
-			free_string(pcdata->history[i][x]);
-		}
-	}
-}
-
 PC_DATA *new_pcdata(void)
 {
-	int alias, bud;
+	int alias, bud, ign;
 
 	static PC_DATA pcdata_zero;
 	PC_DATA *pcdata;
@@ -357,8 +343,12 @@
 	{
 		pcdata->buddies[bud] = NULL;
 	}
-
-	clear_history(pcdata);
+	for (ign = 0; ign < MAX_IGNORE; ign++)
+	{
+		pcdata->ignore[ign] = NULL;
+		pcdata->ignore_flags[ign] = 0;
+	}
+	init_channel_history(pcdata);
 	pcdata->buffer = new_buf();
 	alloc_mem(pcdata->learned, int, maxSkill);
 	alloc_mem(pcdata->group_known, bool, maxGroup);
@@ -369,7 +359,7 @@
 
 void free_pcdata(PC_DATA * pcdata)
 {
-	int alias, pos;
+	int alias, pos, ignore;
 
 	if (!IS_VALID(pcdata))
 		return;
@@ -380,6 +370,7 @@
 	free_string(pcdata->title);
 	free_string(pcdata->who_descr);
 	free_string(pcdata->webpass);
+	free_string(pcdata->afk_msg);
 	free_buf(pcdata->buffer);
 	free_mem(pcdata->learned);
 	free_mem(pcdata->group_known);
@@ -390,8 +381,10 @@
 	}
 	for (pos = 0; pos < MAX_BUDDY; pos++)
 		free_string(pcdata->buddies[pos]);
+	for (ignore = 0; ignore < MAX_IGNORE; ignore++)
+		free_string(pcdata->ignore[ignore]);
 
-	free_history(pcdata);
+	free_channel_history(pcdata);
 
 	INVALIDATE(pcdata);
 
@@ -419,36 +412,10 @@
 	return last_mob_id;
 }
 
-MEM_DATA *mem_data_free;
-
 /* procedures and constants needed for buffering */
 
 BUFFER *buf_free;
 
-MEM_DATA *new_mem_data(void)
-{
-	MEM_DATA *memory;
-
-	GET_FREE(memory, MEM_DATA, next, mem_data_free);
-
-	memory->next = NULL;
-	memory->id = 0;
-	memory->reaction = 0;
-	memory->when = 0;
-	VALIDATE(memory);
-
-	return memory;
-}
-
-void free_mem_data(MEM_DATA * memory)
-{
-	if (!IS_VALID(memory))
-		return;
-
-	INVALIDATE(memory);
-	PUT_FREE(memory, next, mem_data_free);
-}
-
 /* buffer sizes */
 const int buf_size[MAX_BUF_LIST] = {
 	16, 32, 64, 128, 256, 1024, 2048, 4096, 8192, 16384
@@ -497,7 +464,7 @@
 	buffer->size = get_size(size);
 	if (buffer->size == -1)
 	{
-		bug("new_buf: buffer size %d too large.", size);
+		bugf("new_buf: buffer size %d too large.", size);
 		exit(1);
 	}
 	alloc_mem(buffer->string, char, buffer->size);
@@ -521,7 +488,7 @@
 	PUT_FREE(buffer, next, buf_free);
 }
 
-bool add_buf(BUFFER * buffer, const char *string)
+bool bprint(BUFFER * buffer, const char *string)
 {
 	int len;
 	char *oldstr;
@@ -543,7 +510,7 @@
 			{
 				buffer->size = oldsize;
 				buffer->state = BUFFER_OVERFLOW;
-				bug("buffer overflow past size %d", buffer->size);
+				bugf("buffer overflow past size %d", buffer->size);
 				return FALSE;
 			}
 		}
@@ -559,6 +526,43 @@
 
 	strcat(buffer->string, string);
 	return TRUE;
+}
+
+void bprintf(BUFFER * buffer, const char *messg, ...)
+{
+	char buf[MSL * 3];
+	va_list args;
+
+	if (IS_NULLSTR(messg))
+		return;
+
+	va_start(args, messg);
+	vsnprintf(buf, sizeof(buf), messg, args);
+	va_end(args);
+
+	bprint(buffer, buf);
+}
+
+void bprintlnf(BUFFER * buffer, const char *messg, ...)
+{
+	va_list args;
+	char send_buf[MAX_STRING_LENGTH * 3];
+
+	if (IS_NULLSTR(messg))
+		return;
+
+	va_start(args, messg);
+	vsnprintf(send_buf, sizeof(send_buf), messg, args);
+	va_end(args);
+
+	bprint(buffer, send_buf);
+	bprint(buffer, "\n\r");
+}
+
+void bprintln(BUFFER * buffer, const char *messg)
+{
+	bprint(buffer, messg);
+	bprint(buffer, "\n\r");
 }
 
 void clear_buf(BUFFER * buffer)
diff -ur -x config -x o -x rom src/recycle.h new/recycle.h
--- src/recycle.h	Tue May 27 02:46:36 2003
+++ new/recycle.h	Sun Aug 31 19:23:21 2003
@@ -22,18 +22,17 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
 #if !defined(RECYCLE_H)
 #define RECYCLE_H
 
-/* externs */
-extern char str_empty[1];
-extern int mobile_count;
+/* EXTERNs */
+EXTERN char str_empty[1];
 
-int get_size(int val);
+PROTOTYPE(int get_size, (int));
 
 #define GET_FREE(point, type, pnext, freelist) \
 do { \
@@ -67,99 +66,96 @@
 
 /* ban data recycling */
 #define BD BAN_DATA
-BD *new_ban args((void));
-void free_ban args((BAN_DATA * ban));
+PROTOTYPE(BD * new_ban, (void));
+PROTOTYPE(void free_ban, (BAN_DATA *));
 #undef BD
 
 /* descriptor recycling */
 #define DD DESCRIPTOR_DATA
-DD *new_descriptor args((void));
-void free_descriptor args((DESCRIPTOR_DATA * d));
+PROTOTYPE(DD * new_descriptor, (void));
+PROTOTYPE(void free_descriptor, (DESCRIPTOR_DATA *));
 #undef DD
 
 /* char gen data recycling */
 #define GD GEN_DATA
-GD *new_gen_data args((void));
-void free_gen_data args((GEN_DATA * gen));
+PROTOTYPE(GD * new_gen_data, (void));
+PROTOTYPE(void free_gen_data, (GEN_DATA *));
 #undef GD
 
 /* extra descr recycling */
 #define ED EXTRA_DESCR_DATA
-ED *new_extra_descr args((void));
-void free_extra_descr args((EXTRA_DESCR_DATA * ed));
+PROTOTYPE(ED * new_extra_descr, (void));
+PROTOTYPE(void free_extra_descr, (EXTRA_DESCR_DATA *));
 #undef ED
 
 /* affect recycling */
 #define AD AFFECT_DATA
-AD *new_affect args((void));
-void free_affect args((AFFECT_DATA * af));
+PROTOTYPE(AD * new_affect, (void));
+PROTOTYPE(void free_affect, (AFFECT_DATA *));
 #undef AD
 
 /* object recycling */
 #define OD OBJ_DATA
-OD *new_obj args((void));
-void free_obj args((OBJ_DATA * obj));
+PROTOTYPE(OD * new_obj, (void));
+PROTOTYPE(void free_obj, (OBJ_DATA *));
 #undef OD
 
 /* character recyling */
 #define CD CHAR_DATA
 #define PD PC_DATA
-CD *new_char args((void));
-void free_char args((CHAR_DATA * ch));
-PD *new_pcdata args((void));
-void free_pcdata args((PC_DATA * pcdata));
+PROTOTYPE(CD * new_char, (void));
+PROTOTYPE(void free_char, (CHAR_DATA *));
+PROTOTYPE(PD * new_pcdata, (void));
+PROTOTYPE(void free_pcdata, (PC_DATA *));
 #undef PD
 #undef CD
 
-/* mob id and memory procedures */
-#define MD MEM_DATA
-long get_pc_id args((void));
-long get_mob_id args((void));
-MD *new_mem_data args((void));
-void free_mem_data args((MEM_DATA * memory));
-MD *find_memory args((MEM_DATA * memory, long id));
-#undef MD
-
 /* buffer procedures */
-BUFFER *new_buf args((void));
-BUFFER *new_buf_size args((int size));
-void free_buf args((BUFFER * buffer));
-bool add_buf args((BUFFER * buffer, const char *string));
-void clear_buf args((BUFFER * buffer));
-char *buf_string args((BUFFER * buffer));
+PROTOTYPE(BUFFER * new_buf, (void));
+PROTOTYPE(BUFFER * new_buf_size, (int size));
+PROTOTYPE(void free_buf, (BUFFER * buffer));
+PROTOTYPE(bool bprint, (BUFFER * buffer, const char *string));
+PROTOTYPEF(void bprintf, (BUFFER * buffer, const char *messg, ...), 2, 3);
+PROTOTYPEF(void bprintlnf, (BUFFER * buffer, const char *messg, ...), 2, 3);
+PROTOTYPE(void bprintln, (BUFFER * buffer, const char *messg));
+PROTOTYPE(void clear_buf, (BUFFER * buffer));
+PROTOTYPE(char *buf_string, (BUFFER * buffer));
+
+PROTOTYPE(long get_mob_id, (void));
+PROTOTYPE(long get_pc_id, (void));
 
-HELP_DATA *new_help args((void));
-void free_help args((HELP_DATA *));
+PROTOTYPE(HELP_DATA * new_help, (void));
+PROTOTYPE(void free_help, (HELP_DATA *));
 
 /* statlist data recycling */
-STAT_DATA *new_stat_data args((void));
-void free_stat_data args((STAT_DATA * stat));
+PROTOTYPE(STAT_DATA * new_stat_data, (void));
+PROTOTYPE(void free_stat_data, (STAT_DATA *));
 
-CORPSE_DATA *new_corpse args((void));
-void free_corpse args((CORPSE_DATA * corpse));
+PROTOTYPE(CORPSE_DATA * new_corpse, (void));
+PROTOTYPE(void free_corpse, (CORPSE_DATA *));
 
-AUCTION_DATA *new_auction args((void));
-void free_auction args((AUCTION_DATA * auction));
+PROTOTYPE(AUCTION_DATA * new_auction, (void));
+PROTOTYPE(void free_auction, (AUCTION_DATA *));
 
-void free_pwd args((WPWD_DATA * pwd));
-WPWD_DATA *new_pwd args((void));
+PROTOTYPE(void free_pwd, (WPWD_DATA *));
+PROTOTYPE(WPWD_DATA * new_pwd, (void));
 
-MBR_DATA *new_mbr args((void));
-void free_mbr args((MBR_DATA * mbr));
+PROTOTYPE(MBR_DATA * new_mbr, (void));
+PROTOTYPE(void free_mbr, (MBR_DATA *));
 
-RACE_DATA *new_race args((void));
-void free_race args((RACE_DATA * race));
+PROTOTYPE(RACE_DATA * new_race, (void));
+PROTOTYPE(void free_race, (RACE_DATA *));
 
-SOCIAL_DATA *new_social args((void));
-void free_social args((SOCIAL_DATA * soc));
+PROTOTYPE(SOCIAL_DATA * new_social, (void));
+PROTOTYPE(void free_social, (SOCIAL_DATA *));
 
-DEITY_DATA *new_deity args((void));
-void free_deity args((DEITY_DATA * deity));
+PROTOTYPE(DEITY_DATA * new_deity, (void));
+PROTOTYPE(void free_deity, (DEITY_DATA *));
 
-CLAN_DATA *new_clan args((void));
-void free_clan args((CLAN_DATA * clan));
+PROTOTYPE(CLAN_DATA * new_clan, (void));
+PROTOTYPE(void free_clan, (CLAN_DATA *));
 
-CMD_DATA *new_command args((void));
-void free_command args((CMD_DATA * cmd));
+PROTOTYPE(CMD_DATA * new_command, (void));
+PROTOTYPE(void free_command, (CMD_DATA *));
 
 #endif
diff -ur -x config -x o -x rom src/save.c new/save.c
--- src/save.c	Tue May 27 02:46:36 2003
+++ new/save.c	Sun Aug 31 19:23:21 2003
@@ -22,41 +22,97 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "recycle.h"
 #include "tables.h"
 #include "lookup.h"
+#include "interp.h"
+#include "save.h"
+#include "signals.h"
 
-extern int _filbuf args((FILE *));
-
-/* int rename(const char *oldfname, const char *newfname); viene en stdio.h */
-
-void new_warlist args((CHAR_DATA * ch));
-void free_warlist args((WAR_LIST * wl));
-void new_gqlist args((CHAR_DATA * ch));
-void free_gqlist args((GQ_LIST * gql));
-
-/*
- * Array of containers read for proper re-nesting of objects.
- */
-#define MAX_NEST	100
 static OBJ_DATA *rgObjNest[MAX_NEST];
 
+PROTOTYPE(void new_warlist, (CHAR_DATA *));
+PROTOTYPE(void free_warlist, (WAR_DATA *));
+PROTOTYPE(void new_gqlist, (CHAR_DATA *));
+PROTOTYPE(void free_gqlist, (GQ_DATA *));
+
 /*
  * Local functions.
  */
-void fwrite_char args((CHAR_DATA * ch, FILE * fp));
-void fwrite_pet args((CHAR_DATA * pet, FILE * fp));
-void fread_pet args((CHAR_DATA * ch, FILE * fp));
+PROTOTYPE(void fwrite_char, (CHAR_DATA *, FILE *));
+PROTOTYPE(void fwrite_pet, (CHAR_DATA *, FILE *));
+PROTOTYPE(void read_pet, (CHAR_DATA *, READ_DATA *));
+PROTOTYPE(void read_descriptor, (DESCRIPTOR_DATA *, READ_DATA *));
+PROTOTYPE(void fwrite_descriptor, (DESCRIPTOR_DATA *, FILE *));
+
+#define TAB_SIZE    8
+
+char *format_tabs(int len)
+{
+	if (len <= 0)
+		return "";
+	else if (len < TAB_SIZE)
+		return "\t\t";
+	else if (len < (TAB_SIZE * 2))
+		return "\t";
+	else
+		return " ";
+}
+
+/* print *str if not the same as *not, formating *name */
+void fwrite_string(FILE * fp, const char *name, const char *str,
+				   const char *def)
+{
+	if (IS_NULLSTR(name))
+		fprintf(fp, "%s~\n", fix_string(str));
+	else if (!IS_NULLSTR(str) && (IS_NULLSTR(def) || str_cmp(str, def)))
+		fprintf(fp, "%s%s%s~\n", name, format_tabs(strlen(name)),
+				fix_string(str));
+}
+
+/* wrap *str in quotes ('') if not the same as *not, formating *name */
+void fwrite_word(FILE * fp, const char *name, const char *str, const char *def)
+{
+	if (IS_NULLSTR(name))
+		fprintf(fp, "'%s'\n", fix_string(str));
+	else if (!IS_NULLSTR(str) && (IS_NULLSTR(def) || str_cmp(str, def)))
+		fprintf(fp, "%s%s'%s'\n", name, format_tabs(strlen(name)),
+				fix_string(str));
+}
+
+/* print bit if not the same as not, formating *name */
+
+void fwrite_bit(FILE * fp, const char *name, flag_t bit, flag_t def)
+{
+	if (IS_NULLSTR(name))
+		fprintf(fp, "%s\n", fwrite_flags(bit));
+	else if (bit != def)
+		fprintf(fp, "%s%s%s\n", name, format_tabs(strlen(name)),
+				fwrite_flags(bit));
+}
+
+/* print *format, formating *name */
+
+void fwritef(FILE * fp, const char *name, const char *format, ...)
+{
+	va_list args;
+
+	va_start(args, format);
+
+	if (IS_NULLSTR(name))
+		vfprintf(fp, format, args);
+	else
+	{
+		fprintf(fp, "%s%s", name, format_tabs(strlen(name)));
+		vfprintf(fp, format, args);
+	}
+	va_end(args);
+	fprintf(fp, "\n");
+}
 
 /*
  * Save a character and inventory.
@@ -66,7 +122,7 @@
 void save_char_obj(CHAR_DATA * ch)
 {
 	char strsave[MAX_INPUT_LENGTH];
-	FILE *fp;
+	WRITE_DATA *fp;
 
 	if (IS_NPC(ch))
 		return;
@@ -74,45 +130,25 @@
 	if (ch->desc != NULL && ch->desc->original != NULL)
 		ch = ch->desc->original;
 
-	/* create god log */
-	if (IS_IMMORTAL(ch) || ch->level >= LEVEL_IMMORTAL)
-	{
-		sprintf(strsave, "%s%s", GOD_DIR, capitalize(ch->name));
-		if ((fp = file_open(strsave, "w")) == NULL)
-		{
-			bug("Save_char_obj: file_open", 0);
-			perror(strsave);
-		}
-
-		fprintf(fp, "Lev %2d Trust %2d  %s%s\n", ch->level,
-				get_trust(ch), ch->name, ch->pcdata->title);
-		file_close(fp);
-	}
-
 	sprintf(strsave, "%s%s", PLAYER_DIR, capitalize(ch->name));
-#if !defined(WIN32)
-	if ((fp = file_open(TEMP_FILE, "w")) == NULL)
-#else
-	if ((fp = file_open(strsave, "w")) == NULL)
-#endif
+	if ((fp = open_write(strsave)) == NULL)
 	{
-		bug("Save_char_obj: file_open", 0);
-		perror(strsave);
+		bug("Save_char_obj: file open");
+		log_error(strsave);
 	}
 	else
 	{
-		fwrite_char(ch, fp);
+		fwrite_char(ch, fp->stream);
 		if (ch->first_carrying != NULL)
-			fwrite_obj(ch, ch->first_carrying, fp, 0, "O");
+			fwrite_obj(ch, ch->first_carrying, fp->stream, 0, "O");
 		/* save the pets */
 		if (ch->pet != NULL && ch->pet->in_room == ch->in_room)
-			fwrite_pet(ch->pet, fp);
-		fprintf(fp, "#END\n");
+			fwrite_pet(ch->pet, fp->stream);
+		if (ch->desc && (crs_info.status == CRS_COPYOVER || crash_info.crashed))
+			fwrite_descriptor(ch->desc, fp->stream);
+		fprintf(fp->stream, "#END\n");
+		close_write(fp);
 	}
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMP_FILE, strsave);
-#endif
 	return;
 }
 
@@ -127,185 +163,117 @@
 
 	fprintf(fp, "#%s\n", IS_NPC(ch) ? "MOB" : "PLAYER");
 
-	fprintf(fp, "Name %s~\n", ch->name);
-	fprintf(fp, "Id   %ld\n", ch->id);
-	fprintf(fp, "LogO %ld\n", current_time);
-	fprintf(fp, "Vers %d\n", 8);
-	if (ch->short_descr[0] != '\0')
-		fprintf(fp, "ShD  %s~\n", ch->short_descr);
-	if (ch->long_descr[0] != '\0')
-		fprintf(fp, "LnD  %s~\n", ch->long_descr);
-	if (ch->description[0] != '\0')
-		fprintf(fp, "Desc %s~\n", ch->description);
-	if (ch->prompt != NULL || !str_cmp(ch->prompt, "<%hhp %mm %vmv> "))
-		fprintf(fp, "Prom %s~\n", ch->prompt);
-	fprintf(fp, "Race %s~\n", ch->race->name);
+	fwrite_string(fp, "Name", ch->name, NULL);
+	fwrite_int(fp, "Id", "%ld", ch->id, 0);
+	fwrite_int(fp, "LogO", "%ld", current_time, 0);
+	fwrite_int(fp, "Vers", "%d", 9, 0);
+	fwrite_string(fp, "ShD", ch->short_descr, NULL);
+	fwrite_string(fp, "LnD", ch->long_descr, NULL);
+	fwrite_string(fp, "Desc", ch->description, NULL);
+	fwrite_string(fp, "Prom", ch->prompt, NULL);
+	fwrite_string(fp, "Race", ch->race->name, NULL);
 	if (ch->clan != NULL)
 	{
-		fprintf(fp, "Clan %s~\n", ch->clan->name);
-		fprintf(fp, "Rank %d\n", ch->rank);
+		fwrite_string(fp, "Clan", ch->clan->name, NULL);
+		fwrite_int(fp, "Rank", "%d", ch->rank, -1);
 	}
-	fprintf(fp, "Sex  %d\n", ch->sex);
-	fprintf(fp, "Cla  %s\n", class_numbers(ch, TRUE));
+	fwrite_int(fp, "Sex", "%d", ch->sex, -1);
+	fwritef(fp, "Cla", "%s", class_numbers(ch, TRUE));
 	if (ch->pcdata->stay_race)
 		fprintf(fp, "StayRace\n");
-	fprintf(fp, "Levl %d\n", ch->level);
-	if (ch->trust != 0)
-		fprintf(fp, "Tru  %d\n", ch->trust);
-	fprintf(fp, "Sec  %d\n", ch->pcdata->security);	/* OLC */
-	fprintf(fp, "Plyd %d\n", ch->played + (int) (current_time - ch->logon));
-	fprintf(fp, "Scro %d\n", ch->lines);
-	fprintf(fp, "Room %ld\n",
-			(ch->in_room == get_room_index(ROOM_VNUM_LIMBO) &&
-			 ch->was_in_room !=
-			 NULL) ? ch->was_in_room->vnum : ch->in_room ==
-			NULL ? 3001 : ch->in_room->vnum);
-
-	fprintf(fp, "HMV  %ld %ld %ld %ld %ld %ld\n", ch->hit, ch->max_hit,
-			ch->mana, ch->max_mana, ch->move, ch->max_move);
-	if (ch->gold > 0)
-		fprintf(fp, "Gold %ld\n", ch->gold);
-	else
-		fprintf(fp, "Gold %d\n", 0);
-	if (ch->silver > 0)
-		fprintf(fp, "Silv %ld\n", ch->silver);
-	else
-		fprintf(fp, "Silv %d\n", 0);
-	fprintf(fp, "Exp  %d\n", ch->exp);
-	if (ch->act != 0)
-		fprintf(fp, "Act  %s\n", fwrite_flags(ch->act));
-	if (ch->affected_by != 0)
-		fprintf(fp, "AfBy %s\n", fwrite_flags(ch->affected_by));
-	fprintf(fp, "Comm %s\n", fwrite_flags(ch->comm));
-	if (ch->wiznet)
-		fprintf(fp, "Wizn %s\n", fwrite_flags(ch->wiznet));
-	if (ch->invis_level)
-		fprintf(fp, "Invi %d\n", ch->invis_level);
-	if (ch->incog_level)
-		fprintf(fp, "Inco %d\n", ch->incog_level);
-	fprintf(fp, "Pos  %d\n",
-			ch->position == POS_FIGHTING ? POS_STANDING : ch->position);
-	if (ch->practice != 0)
-		fprintf(fp, "Prac %d\n", ch->practice);
-	if (ch->train != 0)
-		fprintf(fp, "Trai %d\n", ch->train);
-	if (ch->saving_throw != 0)
-		fprintf(fp, "Save  %d\n", ch->saving_throw);
-	fprintf(fp, "Alig  %d\n", ch->alignment);
-	if (ch->hitroll != 0)
-		fprintf(fp, "Hit   %d\n", ch->hitroll);
-	if (ch->damroll != 0)
-		fprintf(fp, "Dam   %d\n", ch->damroll);
-	fprintf(fp, "ACs %d %d %d %d\n", ch->armor[0], ch->armor[1],
-			ch->armor[2], ch->armor[3]);
-	if (ch->wimpy != 0)
-		fprintf(fp, "Wimp  %d\n", ch->wimpy);
-	fprintf(fp, "Attr %d %d %d %d %d\n", ch->perm_stat[STAT_STR],
-			ch->perm_stat[STAT_INT], ch->perm_stat[STAT_WIS],
-			ch->perm_stat[STAT_DEX], ch->perm_stat[STAT_CON]);
-
-	fprintf(fp, "AMod %d %d %d %d %d\n", ch->mod_stat[STAT_STR],
-			ch->mod_stat[STAT_INT], ch->mod_stat[STAT_WIS],
-			ch->mod_stat[STAT_DEX], ch->mod_stat[STAT_CON]);
-
+	fwrite_int(fp, "Levl", "%d", ch->level, 0);
+	fwrite_int(fp, "Tru", "%d", ch->trust, 0);
+	fwrite_int(fp, "Sec", "%d", ch->pcdata->security, 0);	/* OLC */
+	fwrite_int(fp, "Plyd", "%d", ch->played + (int) (current_time - ch->logon),
+			   0);
+	fwrite_int(fp, "Scro", "%d", ch->lines, -1);
+	fwrite_int(fp, "Cols", "%d", ch->columns, -1);
+	fwrite_int(fp, "Room", "%ld",
+			   (ch->in_room == get_room_index(ROOM_VNUM_LIMBO) &&
+				ch->was_in_room !=
+				NULL) ? ch->was_in_room->vnum : ch->in_room ==
+			   NULL ? 3001 : ch->in_room->vnum, 0);
+
+	fwritef(fp, "HMV", "%ld %ld %ld %ld %ld %ld", ch->hit,
+			ch->max_hit, ch->mana, ch->max_mana, ch->move, ch->max_move);
+	fwrite_int(fp, "Gold", "%ld", ch->gold, 0);
+	fwrite_int(fp, "Silv", "%ld", ch->silver, 0);
+	fwrite_int(fp, "Exp", "%d", ch->exp, 0);
+	fwrite_bit(fp, "Act", ch->act, 0);
+	fwrite_bit(fp, "AfBy", ch->affected_by, 0);
+	fwrite_bit(fp, "Comm", ch->comm, 0);
+	fwrite_bit(fp, "Wizn", ch->wiznet, 0);
+	fwrite_int(fp, "Invi", "%d", ch->invis_level, 0);
+	fwrite_int(fp, "Inco", "%d", ch->incog_level, 0);
+	fwrite_int(fp, "Pos", "%d",
+			   ch->position == POS_FIGHTING ? POS_STANDING : ch->position, -1);
+	fwrite_int(fp, "Prac", "%d", ch->practice, 0);
+	fwrite_int(fp, "Trai", "%d", ch->train, 0);
+	fwrite_int(fp, "Save", "%d", ch->saving_throw, 0);
+	fwrite_int(fp, "Alig", "%d", ch->alignment, 0);
+	fwrite_int(fp, "Hit", "%d", ch->hitroll, 0);
+	fwrite_int(fp, "Dam", "%d", ch->damroll, 0);
+	fwrite_array("ACs", "%d", ch->armor, 4);
+	fwrite_array("Stance", "%d", ch->stance, MAX_STANCE);
+	fwrite_int(fp, "Wimp", "%d", ch->wimpy, 0);
+	fwrite_array("Attr", "%d", ch->perm_stat, MAX_STATS);
+	fwrite_array("AMod", "%d", ch->mod_stat, MAX_STATS);
 	if (IS_NPC(ch))
 	{
-		fprintf(fp, "Vnum %ld\n", ch->pIndexData->vnum);
+		fwrite_int(fp, "Vnum", "%ld", ch->pIndexData->vnum, 0);
 	}
 	else
 	{
-		fprintf(fp, "Pass %s~\n", ch->pcdata->pwd);
-		if (ch->pcdata->bamfin[0] != '\0')
-			fprintf(fp, "Bin  %s~\n", ch->pcdata->bamfin);
-		if (ch->pcdata->bamfout[0] != '\0')
-			fprintf(fp, "Bout %s~\n", ch->pcdata->bamfout);
-		fprintf(fp, "Titl %s~\n", ch->pcdata->title);
-		fprintf(fp, "Pnts %d\n", ch->pcdata->points);
-		fprintf(fp, "TSex %d\n", ch->pcdata->true_sex);
-		fprintf(fp, "LLev %d\n", ch->pcdata->last_level);
-		fprintf(fp, "HMVP %ld %ld %ld\n", ch->pcdata->perm_hit,
+		fwrite_string(fp, "Pass", ch->pcdata->pwd, NULL);
+		fwrite_string(fp, "Bin", ch->pcdata->bamfin, NULL);
+		fwrite_string(fp, "Bout", ch->pcdata->bamfout, NULL);
+		fwrite_string(fp, "Titl", ch->pcdata->title, NULL);
+		fwrite_int(fp, "Pnts", "%d", ch->pcdata->points, 0);
+		fwrite_int(fp, "TSex", "%d", ch->pcdata->true_sex, -1);
+		fwrite_int(fp, "LLev", "%d", ch->pcdata->last_level, 0);
+		fwritef(fp, "HMVP", "%ld %ld %ld", ch->pcdata->perm_hit,
 				ch->pcdata->perm_mana, ch->pcdata->perm_move);
-		fprintf(fp, "Cnd  %d %d %d %d\n", ch->pcdata->condition[0],
-				ch->pcdata->condition[1], ch->pcdata->condition[2],
-				ch->pcdata->condition[3]);
-
-		if (ch->pcdata->questpoints != 0)
-			fprintf(fp, "QuestPnts %d\n", ch->pcdata->questpoints);
-		if (ch->pcdata->nextquest != 0)
-			fprintf(fp, "QuestNext %d\n", ch->pcdata->nextquest);
-		else if (ch->pcdata->countdown != 0)
-			fprintf(fp, "QuestCount %d\n", ch->pcdata->countdown);
-		if (ch->pcdata->questgiver != 0)
-			fprintf(fp, "QuestGiver %ld\n", ch->pcdata->questgiver);
-		if (ch->pcdata->questloc != 0)
-			fprintf(fp, "QuestLoc   %ld\n", ch->pcdata->questloc);
-		if (ch->pcdata->questobj != 0)
-			fprintf(fp, "QuestObj %ld\n", ch->pcdata->questobj);
-		else if (ch->pcdata->questmob != 0)
-			fprintf(fp, "QuestMob %ld\n", ch->pcdata->questmob);
-		if (ch->pcdata->trivia != 0)
-			fprintf(fp, "Trivia  %d\n", ch->pcdata->trivia);
-
+		fwrite_array("Cnd", "%d", ch->pcdata->condition, 4);
+		fwrite_int(fp, "QuestPnts", "%d", ch->pcdata->questpoints, 0);
+		fwrite_int(fp, "QuestNext", "%d", ch->pcdata->nextquest, 0);
+		fwrite_int(fp, "QuestCount", "%d", ch->pcdata->countdown, 0);
+		fwrite_int(fp, "QuestGiver", "%ld", ch->pcdata->questgiver, 0);
+		fwrite_int(fp, "QuestLoc", "%ld", ch->pcdata->questloc, 0);
+		fwrite_int(fp, "QuestObj", "%ld", ch->pcdata->questobj, 0);
+		fwrite_int(fp, "QuestMob", "%ld", ch->pcdata->questmob, 0);
+		fwrite_int(fp, "Trivia", "%d", ch->pcdata->trivia, 0);
 		if (ch->pcdata->str_ed_key != '.' && ch->pcdata->str_ed_key != ' ')
-			fprintf(fp, "StrEdKey %c\n", ch->pcdata->str_ed_key);
-
-		fprintf(fp, "TimeZone %d\n", ch->pcdata->timezone);
-
-		if (ch->pcdata->awins != 0)
-			fprintf(fp, "AWins  %d\n", ch->pcdata->awins);
-
-		if (ch->pcdata->alosses != 0)
-			fprintf(fp, "ALosses %d\n", ch->pcdata->alosses);
-
-		if (ch->pcdata->silver_bank != 0)
-			fprintf(fp, "BankS  %ld\n", ch->pcdata->silver_bank);
-
-		if (ch->pcdata->gold_bank != 0)
-			fprintf(fp, "BankG  %ld\n", ch->pcdata->gold_bank);
-
-		if (ch->pcdata->shares != 0)
-			fprintf(fp, "Shares %d\n", ch->pcdata->shares);
-
+			fwritef(fp, "StrEdKey", "%c", ch->pcdata->str_ed_key);
+		fwrite_int(fp, "TimeZone", "%d", ch->pcdata->timezone, -1);
+		fwrite_int(fp, "AWins", "%d", ch->pcdata->awins, 0);
+		fwrite_int(fp, "ALosses", "%d", ch->pcdata->alosses, 0);
+		fwrite_int(fp, "BankS", "%ld", ch->pcdata->silver_bank, 0);
+		fwrite_int(fp, "BankG", "%ld", ch->pcdata->gold_bank, 0);
+		fwrite_int(fp, "Shares", "%d", ch->pcdata->shares, 0);
 		if (ch->deity != NULL)
-			fprintf(fp, "Deity %s~\n", ch->deity->name);
-
+			fwrite_string(fp, "Deity", ch->deity->name, NULL);
 		if (ON_GQUEST(ch))
 		{
-			fprintf(fp, "GQmobs ");
-			for (i = 0; i < gquest_info.mob_count; i++)
-				fprintf(fp, "%ld ", ch->gquest->gq_mobs[i]);
-			fprintf(fp, "\n");
+			fwrite_array("GQmobs", "%ld", ch->gquest->gq_mobs,
+						 gquest_info.mob_count);
 		}
-
 		if (war_info.status != WAR_OFF && ch->war != NULL)
 		{
-			fprintf(fp, "WarInfo  %ld %ld %ld %s\n", ch->war->hit,
+			fwritef(fp, "WarInfo", "%ld %ld %ld %s", ch->war->hit,
 					ch->war->mana, ch->war->move, fwrite_flags(ch->war->flags));
 		}
-
 		if (count_home(ch) > 0)
 		{
-			fprintf(fp, "Homes  %d ", MAX_HOUSE_ROOMS);
-			for (i = 0; i < MAX_HOUSE_ROOMS; i++)
-				fprintf(fp, "%ld ", ch->pcdata->home[i]);
-			fprintf(fp, "\n");
-			fprintf(fp, "HKey  %ld\n", ch->pcdata->home_key);
+			fwrite_array("Homes", "%ld", ch->pcdata->home, MAX_HOUSE_ROOMS);
+			fwrite_int(fp, "HKey", "%ld", ch->pcdata->home_key, 0);
 		}
-
-		fprintf(fp, "Colo  %d ", MAX_CUSTOM_COLOUR);
+		fprintf(fp, "Colo\t\t%d", MAX_CUSTOM_COLOUR);
 		for (i = 0; i < MAX_CUSTOM_COLOUR; i++)
-			for (j = 0; j < 3; j++)
-				fprintf(fp, "%d ", ch->pcdata->colour[i][j]);
+			for (j = 0; j < CT_MAX; j++)
+				fprintf(fp, " %d", ch->pcdata->colour[i][j]);
 		fprintf(fp, "\n");
-
-		if (ch->pcdata->who_descr[0] != '\0')
-			fprintf(fp, "WhoD  %s~\n", ch->pcdata->who_descr);
-
-		fprintf(fp, "GStats  %d ", MAX_GAMESTAT);
-		for (i = 0; i < MAX_GAMESTAT; i++)
-			fprintf(fp, "%ld ", ch->pcdata->gamestat[i]);
-		fprintf(fp, "\n");
-
+		fwrite_string(fp, "WhoD", ch->pcdata->who_descr, NULL);
+		fwrite_array("GStats", "%ld", ch->pcdata->gamestat, MAX_GAMESTAT);
 		/* write alias */
 		for (pos = 0; pos < MAX_ALIAS; pos++)
 		{
@@ -313,31 +281,36 @@
 				ch->pcdata->alias_sub[pos] == NULL)
 				break;
 
-			fprintf(fp, "Alias %s %s~\n", ch->pcdata->alias[pos],
+			fwritef(fp, "Alias", "%s %s~", ch->pcdata->alias[pos],
 					ch->pcdata->alias_sub[pos]);
 		}
-
 		for (pos = 0; pos < MAX_BUDDY; pos++)
 		{
 			if (ch->pcdata->buddies[pos] == NULL)
 				break;
 
-			fprintf(fp, "Buddy %s~\n", ch->pcdata->buddies[pos]);
+			fwrite_string(fp, "Buddy", ch->pcdata->buddies[pos], NULL);
 		}
+		for (pos = 0; pos < MAX_IGNORE; pos++)
+		{
+			if (IS_NULLSTR(ch->pcdata->ignore[pos]))
+				break;
 
+			fwritef(fp, "Ignore", "%s~ %s", ch->pcdata->ignore[pos],
+					fwrite_flags(ch->pcdata->ignore_flags[pos]));
+		}
 		/* Save note board status */
 		/* Save number of boards in case that number changes */
-		fprintf(fp, "Boards       %d ", MAX_BOARD);
+		fprintf(fp, "Boards\t\t %d", MAX_BOARD);
 		for (i = 0; i < MAX_BOARD; i++)
-			fprintf(fp, "%s %ld ", boards[i].short_name,
+			fprintf(fp, " %s %ld", boards[i].short_name,
 					ch->pcdata->last_note[i]);
 		fprintf(fp, "\n");
-
 		for (sn = 0; sn < maxSkill; sn++)
 		{
 			if (skill_table[sn].name != NULL && ch->pcdata->learned[sn] > 0)
 			{
-				fprintf(fp, "Sk %d '%s'\n",
+				fwritef(fp, "Sk", "%d '%s'",
 						ch->pcdata->learned[sn], skill_table[sn].name);
 			}
 		}
@@ -346,7 +319,7 @@
 		{
 			if (group_table[gn].name != NULL && ch->pcdata->group_known[gn])
 			{
-				fprintf(fp, "Gr '%s'\n", group_table[gn].name);
+				fwritef(fp, "Gr", "'%s'", group_table[gn].name);
 			}
 		}
 	}
@@ -356,7 +329,7 @@
 		if (paf->type < 0 || paf->type >= maxSkill)
 			continue;
 
-		fprintf(fp, "Affc '%s' %3d %3d %3d %3d %3d %s\n",
+		fwritef(fp, "Affc", "'%s' %3d %3d %3d %3d %3d %s",
 				skill_table[paf->type].name, paf->where, paf->level,
 				paf->duration, paf->modifier, paf->location,
 				fwrite_flags(paf->bitvector));
@@ -373,62 +346,47 @@
 
 	fprintf(fp, "#PET\n");
 
-	fprintf(fp, "Vnum %ld\n", pet->pIndexData->vnum);
+	fwrite_int(fp, "Vnum", "%ld", pet->pIndexData->vnum, 0);
 
-	fprintf(fp, "Name %s~\n", pet->name);
-	fprintf(fp, "LogO %ld\n", current_time);
-	if (str_cmp(pet->short_descr, pet->pIndexData->short_descr))
-		fprintf(fp, "ShD  %s~\n", pet->short_descr);
-	if (str_cmp(pet->long_descr, pet->pIndexData->long_descr))
-		fprintf(fp, "LnD  %s~\n", pet->long_descr);
-	if (str_cmp(pet->description, pet->pIndexData->description))
-		fprintf(fp, "Desc %s~\n", pet->description);
+	fwrite_string(fp, "Name", pet->name, NULL);
+	fwrite_int(fp, "LogO", "%ld", current_time, 0);
+	fwrite_string(fp, "ShD", pet->short_descr, pet->pIndexData->short_descr);
+	fwrite_string(fp, "LnD", pet->long_descr, pet->pIndexData->long_descr);
+	fwrite_string(fp, "Desc", pet->description, pet->pIndexData->description);
 	if (pet->race != pet->pIndexData->race)
-		fprintf(fp, "Race %s~\n", pet->race->name);
+		fwrite_string(fp, "Race", pet->race->name, NULL);
 	if (pet->clan != NULL)
-		fprintf(fp, "Clan %s~\n", pet->clan->name);
-	fprintf(fp, "Sex  %d\n", pet->sex);
-	if (pet->level != pet->pIndexData->level)
-		fprintf(fp, "Levl %d\n", pet->level);
-	fprintf(fp, "HMV  %ld %ld %ld %ld %ld %ld\n", pet->hit, pet->max_hit,
+		fwrite_string(fp, "Clan", pet->clan->name, NULL);
+	fwrite_int(fp, "Sex", "%d", pet->sex, -1);
+	fwrite_int(fp, "Levl", "%d", pet->level, pet->pIndexData->level);
+	fwritef(fp, "HMV", "%ld %ld %ld %ld %ld %ld", pet->hit, pet->max_hit,
 			pet->mana, pet->max_mana, pet->move, pet->max_move);
-	if (pet->gold > 0)
-		fprintf(fp, "Gold %ld\n", pet->gold);
-	if (pet->silver > 0)
-		fprintf(fp, "Silv %ld\n", pet->silver);
-	if (pet->exp > 0)
-		fprintf(fp, "Exp  %d\n", pet->exp);
-	if (pet->act != pet->pIndexData->act)
-		fprintf(fp, "Act  %s\n", fwrite_flags(pet->act));
-	if (pet->affected_by != pet->pIndexData->affected_by)
-		fprintf(fp, "AfBy %s\n", fwrite_flags(pet->affected_by));
-	if (pet->comm != 0)
-		fprintf(fp, "Comm %s\n", fwrite_flags(pet->comm));
-	fprintf(fp, "Pos  %d\n", pet->position =
-			POS_FIGHTING ? POS_STANDING : pet->position);
-	if (pet->saving_throw != 0)
-		fprintf(fp, "Save %d\n", pet->saving_throw);
-	if (pet->alignment != pet->pIndexData->alignment)
-		fprintf(fp, "Alig %d\n", pet->alignment);
-	if (pet->hitroll != pet->pIndexData->hitroll)
-		fprintf(fp, "Hit  %d\n", pet->hitroll);
-	if (pet->damroll != pet->pIndexData->damage[DICE_BONUS])
-		fprintf(fp, "Dam  %d\n", pet->damroll);
-	fprintf(fp, "ACs  %d %d %d %d\n", pet->armor[0], pet->armor[1],
-			pet->armor[2], pet->armor[3]);
-	fprintf(fp, "Attr %d %d %d %d %d\n", pet->perm_stat[STAT_STR],
-			pet->perm_stat[STAT_INT], pet->perm_stat[STAT_WIS],
-			pet->perm_stat[STAT_DEX], pet->perm_stat[STAT_CON]);
-	fprintf(fp, "AMod %d %d %d %d %d\n", pet->mod_stat[STAT_STR],
-			pet->mod_stat[STAT_INT], pet->mod_stat[STAT_WIS],
-			pet->mod_stat[STAT_DEX], pet->mod_stat[STAT_CON]);
+	fwrite_int(fp, "Gold", "%ld", pet->gold, 0);
+	fwrite_int(fp, "Silv", "%ld", pet->silver, 0);
+	fwrite_int(fp, "Exp", "%d", pet->exp, 0);
+	fwrite_bit(fp, "Act", pet->act, pet->pIndexData->act);
+	fwrite_bit(fp, "AfBy", pet->affected_by, pet->pIndexData->affected_by);
+	fwrite_bit(fp, "Comm", pet->comm, 0);
+	fwrite_int(fp, "Pos", "%d", pet->position =
+			   POS_FIGHTING ? POS_STANDING : pet->position, -1);
+	fwrite_int(fp, "Save", "%d", pet->saving_throw, 0);
+	fwrite_int(fp, "Alig", "%d", pet->alignment, pet->pIndexData->alignment);
+	fwrite_int(fp, "Hit", "%d", pet->hitroll, pet->pIndexData->hitroll);
+	fwrite_int(fp, "Dam", "%d", pet->damroll,
+			   pet->pIndexData->damage[DICE_BONUS]);
+
+	fwrite_array("ACs", "%d", pet->armor, 4);
+
+	fwrite_array("Attr", "%d", pet->perm_stat, MAX_STATS);
+
+	fwrite_array("AMod", "%d", pet->mod_stat, MAX_STATS);
 
 	for (paf = pet->first_affect; paf != NULL; paf = paf->next)
 	{
 		if (paf->type < 0 || paf->type >= maxSkill)
 			continue;
 
-		fprintf(fp, "Affc '%s' %3d %3d %3d %3d %3d %s\n",
+		fwritef(fp, "Affc", "'%s' %3d %3d %3d %3d %3d %s",
 				skill_table[paf->type].name, paf->where, paf->level,
 				paf->duration, paf->modifier, paf->location,
 				fwrite_flags(paf->bitvector));
@@ -472,52 +430,36 @@
 											  && !obj->value[0])))
 		return;
 
-	fprintf(fp, "#%s\n", marker);
-	fprintf(fp, "Vnum %ld\n", obj->pIndexData->vnum);
+	fwrite_word(fp, "#", marker, NULL);
+	fwrite_int(fp, "Vnum", "%ld", obj->pIndexData->vnum, 0);
 	if (!ch)
-		fprintf(fp, "Where      %ld\n", where);
-	if (obj->owner != NULL)
-		fprintf(fp, "Owner      %s~\n", obj->owner);
+		fwrite_int(fp, "Where", "%ld", where, ROOM_VNUM_MORGUE);
+	fwrite_string(fp, "Owner", obj->owner, NULL);
 	if (!obj->pIndexData->new_format)
 		fprintf(fp, "Oldstyle\n");
 	if (obj->enchanted)
 		fprintf(fp, "Enchanted\n");
-	fprintf(fp, "Nest %d\n", iNest);
+	fwrite_int(fp, "Nest", "%d", iNest, -1);
 
 	/* these data are only used if they do not match the defaults */
-
-	if (!ch || str_cmp(obj->name, obj->pIndexData->name))
-		fprintf(fp, "Name %s~\n", obj->name);
-	if (!ch || str_cmp(obj->short_descr, obj->pIndexData->short_descr))
-		fprintf(fp, "ShD  %s~\n", obj->short_descr);
-	if (!ch || str_cmp(obj->description, obj->pIndexData->description))
-		fprintf(fp, "Desc %s~\n", obj->description);
-	if (!ch || obj->extra_flags != obj->pIndexData->extra_flags)
-		fprintf(fp, "ExtF %s\n", fwrite_flags(obj->extra_flags));
-	if (!ch || obj->wear_flags != obj->pIndexData->wear_flags)
-		fprintf(fp, "WeaF %s\n", fwrite_flags(obj->wear_flags));
-	if (obj->item_type != obj->pIndexData->item_type)
-		fprintf(fp, "Ityp %d\n", obj->item_type);
-	if (!ch || obj->weight != obj->pIndexData->weight)
-		fprintf(fp, "Wt   %d\n", obj->weight);
-	if (!ch || obj->condition != obj->pIndexData->condition)
-		fprintf(fp, "Cond %d\n", obj->condition);
+	/* new saving functions handle defaults - Markanth 07/07/2003 */
+	fwrite_string(fp, "Name", obj->name, obj->pIndexData->name);
+	fwrite_string(fp, "ShD", obj->short_descr, obj->pIndexData->short_descr);
+	fwrite_string(fp, "Desc", obj->description, obj->pIndexData->description);
+	fwrite_bit(fp, "ExtF", obj->extra_flags, obj->pIndexData->extra_flags);
+	fwrite_bit(fp, "WeaF", obj->wear_flags, obj->pIndexData->wear_flags);
+	fwrite_int(fp, "Ityp", "%d", obj->item_type, obj->pIndexData->item_type);
+	fwrite_int(fp, "Wt", "%d", obj->weight, obj->pIndexData->weight);
+	fwrite_int(fp, "Cond", "%d", obj->condition, obj->pIndexData->condition);
 
 	/* variable data */
 
-	fprintf(fp, "Wear %d\n", obj->wear_loc);
-	if (!ch || obj->level != obj->pIndexData->level)
-		fprintf(fp, "Lev  %d\n", obj->level);
-	if (!ch || obj->timer != 0)
-		fprintf(fp, "Time %d\n", obj->timer);
-	fprintf(fp, "Cost %d\n", obj->cost);
-	if (!ch || (obj->value[0] != obj->pIndexData->value[0] ||
-				obj->value[1] != obj->pIndexData->value[1] ||
-				obj->value[2] != obj->pIndexData->value[2] ||
-				obj->value[3] != obj->pIndexData->value[3] ||
-				obj->value[4] != obj->pIndexData->value[4]))
-		fprintf(fp, "Val  %ld %ld %ld %ld %ld\n", obj->value[0],
-				obj->value[1], obj->value[2], obj->value[3], obj->value[4]);
+	fwrite_int(fp, "Wear", "%d", obj->wear_loc, WEAR_NONE);
+	fwrite_int(fp, "Lev", "%d", obj->level, obj->pIndexData->level);
+	fwrite_int(fp, "Time", "%d", obj->timer, 0);
+	fwrite_int(fp, "Cost", "%d", obj->cost, 0);
+	if (memcmp(obj->value, obj->pIndexData->value, sizeof(obj->value)))
+		fwrite_array("Valu", "%ld", obj->value, 5);
 
 	switch (obj->item_type)
 	{
@@ -526,17 +468,17 @@
 	case ITEM_PILL:
 		if (obj->value[1] > 0)
 		{
-			fprintf(fp, "Spell 1 '%s'\n", skill_table[obj->value[1]].name);
+			fwritef(fp, "Spell 1", "'%s'", skill_table[obj->value[1]].name);
 		}
 
 		if (obj->value[2] > 0)
 		{
-			fprintf(fp, "Spell 2 '%s'\n", skill_table[obj->value[2]].name);
+			fwritef(fp, "Spell 2", "'%s'", skill_table[obj->value[2]].name);
 		}
 
 		if (obj->value[3] > 0)
 		{
-			fprintf(fp, "Spell 3 '%s'\n", skill_table[obj->value[3]].name);
+			fwritef(fp, "Spell 3", "'%s'", skill_table[obj->value[3]].name);
 		}
 
 		break;
@@ -545,7 +487,7 @@
 	case ITEM_WAND:
 		if (obj->value[3] > 0)
 		{
-			fprintf(fp, "Spell 3 '%s'\n", skill_table[obj->value[3]].name);
+			fwritef(fp, "Spell 3", "'%s'", skill_table[obj->value[3]].name);
 		}
 
 		break;
@@ -555,7 +497,7 @@
 	{
 		if (paf->type < 0 || paf->type >= maxSkill)
 			continue;
-		fprintf(fp, "Affc '%s' %3d %3d %3d %3d %3d %s\n",
+		fwritef(fp, "Affc", "'%s' %3d %3d %3d %3d %3d %s",
 				skill_table[paf->type].name, paf->where, paf->level,
 				paf->duration, paf->modifier, paf->location,
 				fwrite_flags(paf->bitvector));
@@ -563,7 +505,7 @@
 
 	for (ed = obj->first_extra_descr; ed != NULL; ed = ed->next)
 	{
-		fprintf(fp, "ExDe %s~ %s~\n", ed->keyword, ed->description);
+		fwritef(fp, "ExDe", "%s~ %s~", ed->keyword, ed->description);
 	}
 
 	fprintf(fp, "End\n\n");
@@ -574,6 +516,45 @@
 	return;
 }
 
+void fwrite_descriptor(DESCRIPTOR_DATA * d, FILE * fp)
+{
+	fprintf(fp, "#DESC\n");
+	fwrite_string(fp, "Host", d->host, NULL);
+	fwrite_int(fp, "Descr", "%d", d->descriptor, 0);
+	fwrite_int(fp, "Connected", "%d", d->connected, 0);
+	fwrite_bit(fp, "Flags", d->d_flags, 0);
+	fwrite_int(fp, "ScrW", "%u", d->scr_width, 80);
+	fwrite_int(fp, "ScrH", "%u", d->scr_height, 24);
+	fwrite_int(fp, "ByteN", "%ld", d->bytes_normal, 0);
+#if !defined(NO_MCCP)
+	fwrite_int(fp, "ByteC", "%ld", d->bytes_compressed, 0);
+	fwrite_int(fp, "CVersion", "%d", d->mccp_version, 0);
+#endif
+	fwrite_string(fp, "TType", d->ttype, NULL);
+	if (IS_MXP(d))
+	{
+		fwrite_string(fp, "MXPSup", d->mxp.supports, NULL);
+		fwrite_int(fp, "MXPVer", "%.2f", d->mxp.mxp_ver, 0);
+		fwrite_int(fp, "MXPClVer", "%.2f", d->mxp.client_ver, 0);
+		fwrite_int(fp, "MXPStyl", "%.2f", d->mxp.style_ver, 0);
+		fwrite_string(fp, "MXPClien", d->mxp.client, NULL);
+		fwrite_int(fp, "MXPReg", "%d", d->mxp.registered, 0);
+		fwrite_bit(fp, "MXPFlag1", d->mxp.flags, 0);
+		fwrite_bit(fp, "MXPFlag2", d->mxp.flags2, 0);
+	}
+	if (IS_PORTAL(d))
+	{
+		fwrite_int(fp, "Keycode", "%u", d->portal.keycode, 0);
+		fwrite_string(fp, "PortVer", d->portal.version, NULL);
+	}
+	if (IS_FIRECL(d))
+		fwrite_int(fp, "IMPver", "%.2f", d->imp_vers, 0);
+	if (IS_PUEBLO(d))
+		fwrite_int(fp, "Pueblo", "%.2f", d->pueblo_vers, 0);
+	fprintf(fp, "End\n\n");
+	return;
+}
+
 void set_player_level(CHAR_DATA * ch, int Old, int New, int version)
 {
 	int diff = MAX_LEVEL - LEVEL_IMMORTAL;
@@ -594,7 +575,7 @@
 {
 	int stat, i, iClass;
 
-	ch->race = race_lookup("human");
+	ch->race = default_race;
 	ch->act = PLR_NOSUMMON | PLR_AUTOMAP;
 	ch->comm = COMM_COMBINE | COMM_PROMPT;
 	for (iClass = 0; iClass < MAX_MCLASS; iClass++)
@@ -609,6 +590,7 @@
 	ch->pcdata->bamfout = str_dup("");
 	ch->pcdata->title = str_dup("");
 	ch->pcdata->who_descr = str_dup("");
+	ch->pcdata->afk_msg = str_dup("");
 	for (stat = 0; stat < MAX_STATS; stat++)
 		ch->perm_stat[stat] = 13;
 	ch->pcdata->condition[COND_THIRST] = 48;
@@ -631,7 +613,7 @@
 	char strsave[MAX_INPUT_LENGTH];
 	char buf[100];
 	CHAR_DATA *ch;
-	FILE *fp;
+	READ_DATA *fp;
 	bool found;
 	int i;
 
@@ -647,15 +629,15 @@
 
 	/* decompress if .gz file exists */
 	sprintf(strsave, "%s%s%s", PLAYER_DIR, capitalize(name), ".gz");
-	if ((fp = file_open(strsave, "r")) != NULL)
+	if ((fp = open_read(strsave)) != NULL)
 	{
-		file_close(fp);
+		close_read(fp);
 		sprintf(buf, "gzip -dfq %s", strsave);
 		system(buf);
 	}
 
 	sprintf(strsave, "%s%s", PLAYER_DIR, capitalize(name));
-	if ((fp = file_open(strsave, "r")) != NULL)
+	if ((fp = open_read(strsave)) != NULL)
 	{
 		int iNest;
 
@@ -668,44 +650,46 @@
 			char letter;
 			char *word;
 
-			letter = fread_letter(fp);
+			letter = read_letter(fp);
 			if (letter == '*')
 			{
-				fread_to_eol(fp);
+				read_to_eol(fp);
 				continue;
 			}
 
 			if (letter != '#')
 			{
-				bug("Load_char_obj: # not found.", 0);
+				bug("Load_char_obj: # not found.");
 				break;
 			}
 
-			word = fread_word(fp);
+			word = read_word(fp);
 			if (!str_cmp(word, "PLAYER"))
-				fread_char(ch, fp);
+				read_char(ch, fp);
 			else if (!str_cmp(word, "OBJECT"))
-				fread_obj(ch, fp, FALSE);
+				read_obj(ch, fp, FALSE);
 			else if (!str_cmp(word, "O"))
-				fread_obj(ch, fp, FALSE);
+				read_obj(ch, fp, FALSE);
 			else if (!str_cmp(word, "PET"))
-				fread_pet(ch, fp);
+				read_pet(ch, fp);
+			else if (!str_cmp(word, "DESC"))
+				read_descriptor(d, fp);
 			else if (!str_cmp(word, "END"))
 				break;
 			else
 			{
-				bug("Load_char_obj: bad section.", 0);
+				bug("Load_char_obj: bad section.");
 				break;
 			}
 		}
+		close_read(fp);
 	}
-	file_close(fp);
 
 	/* initialize race */
 	if (found)
 	{
-		if (ch->race == 0)
-			ch->race = race_lookup("human");
+		if (ch->race == NULL)
+			ch->race = default_race;
 
 		ch->size = ch->race->size;
 		ch->dam_type = 17;		/*punch */
@@ -723,21 +707,12 @@
 		ch->form = ch->race->form;
 		ch->parts = ch->race->parts;
 
-		if (d != NULL)
-		{
-			if (IS_SET(ch->comm, COMM_NOCOLOUR))
-				REMOVE_BIT(d->d_flags, DESC_COLOUR);
-		}
-
 		if (ch->war && war_info.status == WAR_OFF)
 			free_warlist(ch->war);
 
 		if (ch->gquest && gquest_info.running == GQUEST_OFF)
 			free_gqlist(ch->gquest);
-	}
 
-	if (found)
-	{
 		/* Change this to set player levels when changing max level 
 		   The first number is the OLD max level, the second is the
 		   NEW max level, and the third is the new version that should be
@@ -752,33 +727,7 @@
  * Read in a char.
  */
 
-#if defined(KEY)
-#undef KEY
-#endif
-
-#define KEY( literal, field, value )					\
-				if ( !str_cmp( word, literal ) )	\
-				{					\
-				    field  = value;			\
-				    fMatch = TRUE;			\
-				    break;				\
-				}
-
-/* provided to free strings */
-#if defined(KEYS)
-#undef KEYS
-#endif
-
-#define KEYS( literal, field, value )					\
-				if ( !str_cmp( word, literal ) )	\
-				{					\
-				    free_string(field);			\
-				    field  = value;			\
-				    fMatch = TRUE;			\
-				    break;				\
-				}
-
-void fread_char(CHAR_DATA * ch, FILE * fp)
+void read_char(CHAR_DATA * ch, READ_DATA * fp)
 {
 	char buf[MAX_STRING_LENGTH];
 	const char *word;
@@ -787,42 +736,43 @@
 	int count2 = 0;
 	int lastlogoff = current_time;
 	int percent;
+	int ignore = 0;
 
 	sprintf(buf, "Loading %s.", ch->name);
 	log_string(buf);
 
 	for (;;)
 	{
-		word = feof(fp) ? "End" : fread_word(fp);
+		word = steof(fp) ? "End" : read_word(fp);
 		fMatch = FALSE;
 
 		switch (UPPER(word[0]))
 		{
 		case '*':
 			fMatch = TRUE;
-			fread_to_eol(fp);
+			read_to_eol(fp);
 			break;
 
 		case 'A':
-			KEY("Act", ch->act, fread_flag(fp));
-			KEY("AffectedBy", ch->affected_by, fread_flag(fp));
-			KEY("AfBy", ch->affected_by, fread_flag(fp));
-			KEY("Alignment", ch->alignment, fread_number(fp));
-			KEY("Alig", ch->alignment, fread_number(fp));
-			KEY("AWins", ch->pcdata->awins, fread_number(fp));
-			KEY("ALosses", ch->pcdata->alosses, fread_number(fp));
+			KEY("Act", ch->act, read_flag(fp));
+			KEY("AffectedBy", ch->affected_by, read_flag(fp));
+			KEY("AfBy", ch->affected_by, read_flag(fp));
+			KEY("Alignment", ch->alignment, read_number(fp));
+			KEY("Alig", ch->alignment, read_number(fp));
+			KEY("AWins", ch->pcdata->awins, read_number(fp));
+			KEY("ALosses", ch->pcdata->alosses, read_number(fp));
 
 			if (!str_cmp(word, "Alia"))
 			{
 				if (count >= MAX_ALIAS)
 				{
-					fread_to_eol(fp);
+					read_to_eol(fp);
 					fMatch = TRUE;
 					break;
 				}
 
-				ch->pcdata->alias[count] = str_dup(fread_word(fp));
-				ch->pcdata->alias_sub[count] = str_dup(fread_word(fp));
+				ch->pcdata->alias[count] = str_dup(read_word(fp));
+				ch->pcdata->alias_sub[count] = str_dup(read_word(fp));
 				count++;
 				fMatch = TRUE;
 				break;
@@ -832,31 +782,31 @@
 			{
 				if (count >= MAX_ALIAS)
 				{
-					fread_to_eol(fp);
+					read_to_eol(fp);
 					fMatch = TRUE;
 					break;
 				}
 
-				ch->pcdata->alias[count] = str_dup(fread_word(fp));
-				ch->pcdata->alias_sub[count] = fread_string(fp);
+				ch->pcdata->alias[count] = str_dup(read_word(fp));
+				ch->pcdata->alias_sub[count] = read_string(fp);
 				count++;
 				fMatch = TRUE;
 				break;
 			}
-
-			if (!str_cmp(word, "AC") || !str_cmp(word, "Armor"))
-			{
-				fread_to_eol(fp);
-				fMatch = TRUE;
-				break;
-			}
+			KEY_IGNORE("AC");
+			KEY_IGNORE("Armor");
 
 			if (!str_cmp(word, "ACs"))
 			{
-				int i;
+				if (ch->version < 9)
+				{
+					int i;
 
-				for (i = 0; i < 4; i++)
-					ch->armor[i] = fread_number(fp);
+					for (i = 0; i < 4; i++)
+						ch->armor[i] = read_number(fp);
+				}
+				else
+					read_array(ch->armor, 4, 100);
 				fMatch = TRUE;
 				break;
 			}
@@ -868,17 +818,17 @@
 
 				paf = new_affect();
 
-				sn = skill_lookup(fread_word(fp));
+				sn = skill_lookup(read_word(fp));
 				if (sn < 0)
-					bug("Fread_char: unknown skill.", 0);
+					bug("read_char: unknown skill.");
 				else
 					paf->type = sn;
 
-				paf->level = fread_number(fp);
-				paf->duration = fread_number(fp);
-				paf->modifier = fread_number(fp);
-				paf->location = fread_number(fp);
-				paf->bitvector = fread_number(fp);
+				paf->level = read_number(fp);
+				paf->duration = read_number(fp);
+				paf->modifier = read_number(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->bitvector = read_number(fp);
 				LINK(paf, ch->first_affect, ch->last_affect, next, prev);
 				fMatch = TRUE;
 				break;
@@ -891,18 +841,18 @@
 
 				paf = new_affect();
 
-				sn = skill_lookup(fread_word(fp));
+				sn = skill_lookup(read_word(fp));
 				if (sn < 0)
-					bug("Fread_char: unknown skill.", 0);
+					bug("read_char: unknown skill.");
 				else
 					paf->type = sn;
 
-				paf->where = fread_number(fp);
-				paf->level = fread_number(fp);
-				paf->duration = fread_number(fp);
-				paf->modifier = fread_number(fp);
-				paf->location = fread_number(fp);
-				paf->bitvector = fread_flag(fp);
+				paf->where = read_enum(where_t, fp);
+				paf->level = read_number(fp);
+				paf->duration = read_number(fp);
+				paf->modifier = read_number(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->bitvector = read_flag(fp);
 				LINK(paf, ch->first_affect, ch->last_affect, next, prev);
 				fMatch = TRUE;
 				break;
@@ -910,40 +860,50 @@
 
 			if (!str_cmp(word, "AttrMod") || !str_cmp(word, "AMod"))
 			{
-				int stat;
-				for (stat = 0; stat < MAX_STATS; stat++)
-					ch->mod_stat[stat] = fread_number(fp);
+				if (ch->version < 9)
+				{
+					int stat;
+					for (stat = 0; stat < MAX_STATS; stat++)
+						ch->mod_stat[stat] = read_number(fp);
+				}
+				else
+					read_array(ch->mod_stat, MAX_STATS, 3);
 				fMatch = TRUE;
 				break;
 			}
 
 			if (!str_cmp(word, "AttrPerm") || !str_cmp(word, "Attr"))
 			{
-				int stat;
+				if (ch->version < 9)
+				{
+					int stat;
 
-				for (stat = 0; stat < MAX_STATS; stat++)
-					ch->perm_stat[stat] = fread_number(fp);
+					for (stat = 0; stat < MAX_STATS; stat++)
+						ch->perm_stat[stat] = read_number(fp);
+				}
+				else
+					read_array(ch->perm_stat, MAX_STATS, 3);
 				fMatch = TRUE;
 				break;
 			}
 			break;
 
 		case 'B':
-			KEYS("Bamfin", ch->pcdata->bamfin, fread_string(fp));
-			KEYS("Bamfout", ch->pcdata->bamfout, fread_string(fp));
-			KEYS("Bin", ch->pcdata->bamfin, fread_string(fp));
-			KEYS("Bout", ch->pcdata->bamfout, fread_string(fp));
-			KEY("BankS", ch->pcdata->silver_bank, fread_number(fp));
-			KEY("BankG", ch->pcdata->gold_bank, fread_number(fp));
+			KEYS("Bamfin", ch->pcdata->bamfin);
+			KEYS("Bamfout", ch->pcdata->bamfout);
+			KEYS("Bin", ch->pcdata->bamfin);
+			KEYS("Bout", ch->pcdata->bamfout);
+			KEY("BankS", ch->pcdata->silver_bank, read_number(fp));
+			KEY("BankG", ch->pcdata->gold_bank, read_number(fp));
 			if (!str_cmp(word, "Buddy"))
 			{
 				if (count2 >= MAX_BUDDY)
 				{
-					fread_to_eol(fp);
+					read_to_eol(fp);
 					fMatch = TRUE;
 					break;
 				}
-				ch->pcdata->buddies[count2] = fread_string(fp);
+				ch->pcdata->buddies[count2] = read_string(fp);
 				count2++;
 				fMatch = TRUE;
 				break;
@@ -951,27 +911,28 @@
 			/* Read in board status */
 			if (!str_cmp(word, "Boards"))
 			{
-				int i, num = fread_number(fp);	/* number of boards saved */
+				int i, num = read_number(fp);	/* number of boards saved */
 				char *boardname;
 
 				for (; num; num--)	/* for each of the board saved */
 				{
-					boardname = fread_word(fp);
+					boardname = read_word(fp);
 					i = board_lookup(boardname);	/* find board number */
 
 					if (i == BOARD_NOTFOUND)	/* Does board still exist ? */
 					{
 						sprintf(buf,
-								"fread_char: %s had unknown board name: %s. Skipped.",
+								"read_char: %s had unknown board name: %s. Skipped.",
 								ch->name, boardname);
 						log_string(buf);
-						fread_number(fp);	/* read last_note and skip info */
+						read_number(fp);	/* read last_note and skip info */
 					}
 					else		/* Save it */
-						ch->pcdata->last_note[i] = fread_number(fp);
+						ch->pcdata->last_note[i] = read_number(fp);
 				}				/* for */
 
 				fMatch = TRUE;
+				break;
 			}					/* Boards */
 			break;
 
@@ -986,7 +947,7 @@
 					ch->Class[iClass] = -1;
 				for (iClass = 0; iClass < MAX_MCLASS; iClass++)
 				{
-					ch->Class[iClass] = fread_number(fp);
+					ch->Class[iClass] = read_number(fp);
 					if (ch->Class[iClass] == -1)
 						break;
 				}
@@ -1004,71 +965,67 @@
 						invalid = TRUE;
 					}
 				}
-			}
-			if (!str_cmp(word, "Clan"))
-			{
-				const char *tmp = fread_string(fp);
-				ch->clan = clan_lookup(tmp);
-				free_string(tmp);
-				fMatch = TRUE;
 				break;
 			}
+			KEY_SFUN("Clan", ch->clan, clan_lookup);
 			if (!str_cmp(word, "Condition") || !str_cmp(word, "Cond"))
 			{
-				ch->pcdata->condition[0] = fread_number(fp);
-				ch->pcdata->condition[1] = fread_number(fp);
-				ch->pcdata->condition[2] = fread_number(fp);
+				ch->pcdata->condition[0] = read_number(fp);
+				ch->pcdata->condition[1] = read_number(fp);
+				ch->pcdata->condition[2] = read_number(fp);
 				fMatch = TRUE;
 				break;
 			}
 			if (!str_cmp(word, "Cnd"))
 			{
-				ch->pcdata->condition[0] = fread_number(fp);
-				ch->pcdata->condition[1] = fread_number(fp);
-				ch->pcdata->condition[2] = fread_number(fp);
-				ch->pcdata->condition[3] = fread_number(fp);
+				if (ch->version < 9)
+				{
+					ch->pcdata->condition[0] = read_number(fp);
+					ch->pcdata->condition[1] = read_number(fp);
+					ch->pcdata->condition[2] = read_number(fp);
+					ch->pcdata->condition[3] = read_number(fp);
+				}
+				else
+					read_array(ch->pcdata->condition, 4, 0);
 				fMatch = TRUE;
 				break;
 			}
-			KEY("Comm", ch->comm, fread_flag(fp));
+			KEY("Comm", ch->comm, read_flag(fp));
+			KEY("Cols", ch->columns, read_number(fp));
 			if (!str_cmp(word, "Colo"))
 			{
 				if (ch->version >= 8)
 				{
-					int i, j, num = fread_number(fp);
+					int i, j, num = read_number(fp);
 
-					for (i = 0; i < num; i++)
+					for (i = 0; i < UMIN(num, MAX_CUSTOM_COLOUR); i++)
 					{
-						for (j = 0; j < 3; j++)
-							ch->pcdata->colour[i][j] = fread_number(fp);
 						if (i >= MAX_CUSTOM_COLOUR)
 							break;
+						for (j = 0; j < CT_MAX; j++)
+							ch->pcdata->colour[i][j] = read_number(fp);
 					}
 				}
-				fread_to_eol(fp);
+				read_to_eol(fp);
 				fMatch = TRUE;
 				break;
 			}
 			break;
 
 		case 'D':
-			KEY("Damroll", ch->damroll, fread_number(fp));
-			KEY("Dam", ch->damroll, fread_number(fp));
-			KEYS("Description", ch->description, fread_string(fp));
-			KEYS("Desc", ch->description, fread_string(fp));
-			if (!str_cmp(word, "Deity"))
-			{
-				const char *tmp = fread_string(fp);
-				ch->deity = deity_lookup(tmp);
-				free_string(tmp);
-				fMatch = TRUE;
-				break;
-			}
+			KEY("Damroll", ch->damroll, read_number(fp));
+			KEY("Dam", ch->damroll, read_number(fp));
+			KEYS("Description", ch->description);
+			KEYS("Desc", ch->description);
+			KEY_SFUN("Deity", ch->deity, deity_lookup);
 			break;
 
 		case 'E':
 			if (!str_cmp(word, "End"))
 			{
+				if (ch->in_room == NULL)
+					ch->in_room = get_room_index(ROOM_VNUM_LIMBO);
+
 				/* adjust hp mana move up  -- here for speed's sake */
 				percent = (current_time - lastlogoff) * 25 / (2 * 60 * 60);
 
@@ -1083,82 +1040,61 @@
 				}
 				return;
 			}
-			KEY("Exp", ch->exp, fread_number(fp));
+			KEY("Exp", ch->exp, read_number(fp));
 			break;
 
 		case 'G':
-			KEY("Gold", ch->gold, fread_number(fp));
+			KEY("Gold", ch->gold, read_number(fp));
 			if (!str_cmp(word, "GQmobs"))
 			{
-				int i;
-
 				new_gqlist(ch);
-				for (i = 0; i < gquest_info.mob_count; i++)
-					ch->gquest->gq_mobs[i] = fread_number(fp);
-				fread_to_eol(fp);
+				read_array(ch->gquest->gq_mobs, gquest_info.mob_count, -1);
 				fMatch = TRUE;
+				break;
 			}
 			if (!str_cmp(word, "Group") || !str_cmp(word, "Gr"))
 			{
 				int gn;
 				char *temp;
 
-				temp = fread_word(fp);
+				temp = read_word(fp);
 				gn = group_lookup(temp);
-				/* gn    = group_lookup( fread_word( fp ) ); */
+				/* gn    = group_lookup( read_word( fp ) ); */
 				if (gn < 0)
 				{
-					bugf("Fread_char: unknown group (%s). ", temp);
+					bugf("read_char: unknown group (%s). ", temp);
 				}
 				else
 					gn_add(ch, gn);
 				fMatch = TRUE;
-			}
-			if (!str_cmp(word, "GStats"))
-			{
-				int i, maxStat = 0;
-
-				maxStat = fread_number(fp);
-
-				for (i = 0; i < maxStat; i++)
-					ch->pcdata->gamestat[i] = fread_number(fp);
-				fMatch = TRUE;
 				break;
 			}
+			KEY_ARRAY("Gstats", ch->pcdata->gamestat, MAX_GAMESTAT, 0);
 			break;
 
 		case 'H':
-			KEY("Hitroll", ch->hitroll, fread_number(fp));
-			KEY("Hit", ch->hitroll, fread_number(fp));
-			KEY("HKey", ch->pcdata->home_key, fread_number(fp));
-			if (!str_cmp(word, "Homes"))
-			{
-				int i, maxHome = 0;
-
-				maxHome = fread_number(fp);
-				for (i = 0; i < maxHome; i++)
-					ch->pcdata->home[i] = fread_number(fp);
-				fMatch = TRUE;
-				break;
-			}
+			KEY("Hitroll", ch->hitroll, read_number(fp));
+			KEY("Hit", ch->hitroll, read_number(fp));
+			KEY("HKey", ch->pcdata->home_key, read_number(fp));
+			KEY_ARRAY("Homes", ch->pcdata->home, MAX_HOUSE_ROOMS, 0);
 
 			if (!str_cmp(word, "HpManaMove") || !str_cmp(word, "HMV"))
 			{
-				ch->hit = fread_number(fp);
-				ch->max_hit = fread_number(fp);
-				ch->mana = fread_number(fp);
-				ch->max_mana = fread_number(fp);
-				ch->move = fread_number(fp);
-				ch->max_move = fread_number(fp);
+				ch->hit = read_number(fp);
+				ch->max_hit = read_number(fp);
+				ch->mana = read_number(fp);
+				ch->max_mana = read_number(fp);
+				ch->move = read_number(fp);
+				ch->max_move = read_number(fp);
 				fMatch = TRUE;
 				break;
 			}
 
 			if (!str_cmp(word, "HpManaMovePerm") || !str_cmp(word, "HMVP"))
 			{
-				ch->pcdata->perm_hit = fread_number(fp);
-				ch->pcdata->perm_mana = fread_number(fp);
-				ch->pcdata->perm_move = fread_number(fp);
+				ch->pcdata->perm_hit = read_number(fp);
+				ch->pcdata->perm_mana = read_number(fp);
+				ch->pcdata->perm_move = read_number(fp);
 				fMatch = TRUE;
 				break;
 			}
@@ -1166,147 +1102,126 @@
 			break;
 
 		case 'I':
-			KEY("Id", ch->id, fread_number(fp));
-			KEY("InvisLevel", ch->invis_level, fread_number(fp));
-			KEY("Inco", ch->incog_level, fread_number(fp));
-			KEY("Invi", ch->invis_level, fread_number(fp));
+			KEY("Id", ch->id, read_number(fp));
+			KEY("InvisLevel", ch->invis_level, read_number(fp));
+			KEY("Inco", ch->incog_level, read_number(fp));
+			KEY("Invi", ch->invis_level, read_number(fp));
+			if (!str_cmp(word, "Ignore"))
+			{
+				if (ignore >= MAX_IGNORE)
+				{
+					read_to_eol(fp);
+					fMatch = TRUE;
+					break;
+				}
+				ch->pcdata->ignore[ignore] = read_string(fp);
+				ch->pcdata->ignore_flags[ignore] = read_flag(fp);
+				ignore++;
+				fMatch = TRUE;
+				break;
+			}
 			break;
 
 		case 'L':
-			KEY("LastLevel", ch->pcdata->last_level, fread_number(fp));
-			KEY("LLev", ch->pcdata->last_level, fread_number(fp));
-			KEY("Level", ch->level, fread_number(fp));
-			KEY("Lev", ch->level, fread_number(fp));
-			KEY("Levl", ch->level, fread_number(fp));
-			KEY("LogO", lastlogoff, fread_number(fp));
-			KEYS("LongDescr", ch->long_descr, fread_string(fp));
-			KEYS("LnD", ch->long_descr, fread_string(fp));
+			KEY("LastLevel", ch->pcdata->last_level, read_number(fp));
+			KEY("LLev", ch->pcdata->last_level, read_number(fp));
+			KEY("Level", ch->level, read_number(fp));
+			KEY("Lev", ch->level, read_number(fp));
+			KEY("Levl", ch->level, read_number(fp));
+			KEY("LogO", lastlogoff, read_number(fp));
+			KEYS("LongDescr", ch->long_descr);
+			KEYS("LnD", ch->long_descr);
 			break;
 
 		case 'N':
-			KEYS("Name", ch->name, fread_string(fp));
-			if (!str_cmp(word, "Not"))
-			{
-				fread_number(fp);
-				fread_number(fp);
-				fread_number(fp);
-				fread_number(fp);
-				fread_number(fp);
-				fMatch = TRUE;
-				break;
-			}
+			KEYS("Name", ch->name);
+			KEY_IGNORE("Not");
 			break;
 
 		case 'P':
-			KEYS("Password", ch->pcdata->pwd, fread_string(fp));
-			KEYS("Pass", ch->pcdata->pwd, fread_string(fp));
-			KEY("Played", ch->played, fread_number(fp));
-			KEY("Plyd", ch->played, fread_number(fp));
-			KEY("Points", ch->pcdata->points, fread_number(fp));
-			KEY("Pnts", ch->pcdata->points, fread_number(fp));
-			KEY("Position", ch->position, fread_number(fp));
-			KEY("Pos", ch->position, fread_number(fp));
-			KEY("Practice", ch->practice, fread_number(fp));
-			KEY("Prac", ch->practice, fread_number(fp));
-			KEYS("Prompt", ch->prompt, fread_string(fp));
-			KEYS("Prom", ch->prompt, fread_string(fp));
+			KEYS("Password", ch->pcdata->pwd);
+			KEYS("Pass", ch->pcdata->pwd);
+			KEY("Played", ch->played, read_number(fp));
+			KEY("Plyd", ch->played, read_number(fp));
+			KEY("Points", ch->pcdata->points, read_number(fp));
+			KEY("Pnts", ch->pcdata->points, read_number(fp));
+			KEY("Position", ch->position, read_enum(position_t, fp));
+			KEY("Pos", ch->position, read_enum(position_t, fp));
+			KEY("Practice", ch->practice, read_number(fp));
+			KEY("Prac", ch->practice, read_number(fp));
+			KEYS("Prompt", ch->prompt);
+			KEYS("Prom", ch->prompt);
 			break;
 
 		case 'Q':
-			KEY("QuestPnts", ch->pcdata->questpoints, fread_number(fp));
-			KEY("QuestNext", ch->pcdata->nextquest, fread_number(fp));
-			KEY("QuestCount", ch->pcdata->countdown, fread_number(fp));
-			KEY("QuestLoc", ch->pcdata->questloc, fread_number(fp));
-			KEY("QuestObj", ch->pcdata->questobj, fread_number(fp));
-			KEY("QuestGiver", ch->pcdata->questgiver, fread_number(fp));
-			KEY("QuestMob", ch->pcdata->questmob, fread_number(fp));
+			KEY("QuestPnts", ch->pcdata->questpoints, read_number(fp));
+			KEY("QuestNext", ch->pcdata->nextquest, read_number(fp));
+			KEY("QuestCount", ch->pcdata->countdown, read_number(fp));
+			KEY("QuestLoc", ch->pcdata->questloc, read_number(fp));
+			KEY("QuestObj", ch->pcdata->questobj, read_number(fp));
+			KEY("QuestGiver", ch->pcdata->questgiver, read_number(fp));
+			KEY("QuestMob", ch->pcdata->questmob, read_number(fp));
 			break;
 
 		case 'R':
-			KEY("Rank", ch->rank, fread_number(fp));
-			if (!str_cmp(word, "Race"))
-			{
-				const char *tmp = fread_string(fp);
-
-				ch->race = race_lookup(tmp);
-				free_string(tmp);
-				fMatch = TRUE;
-				break;
-			}
-			if (!str_cmp(word, "RoomRLE"))
-			{
-				fread_rle(ch->pcdata->explored, fp);
-				fMatch = TRUE;
-				break;
-			}
-			if (!str_cmp(word, "Room"))
-			{
-				ch->in_room = get_room_index(fread_number(fp));
-				if (ch->in_room == NULL)
-					ch->in_room = get_room_index(ROOM_VNUM_LIMBO);
-				fMatch = TRUE;
-				break;
-			}
-
+			KEY("Rank", ch->rank, read_number(fp));
+			KEY_SFUN("Race", ch->race, race_lookup);
+			KEY_DO("RoomRLE", read_rle(ch->pcdata->explored, fp));
+			KEY_DO("Room", (ch->in_room = get_room_index(read_number(fp))));
 			break;
 
 		case 'S':
-			KEY("SavingThrow", ch->saving_throw, fread_number(fp));
-			KEY("Save", ch->saving_throw, fread_number(fp));
-			KEY("Scro", ch->lines, fread_number(fp));
-			KEY("Sex", ch->sex, fread_number(fp));
-			KEYS("ShortDescr", ch->short_descr, fread_string(fp));
-			KEYS("ShD", ch->short_descr, fread_string(fp));
-			KEY("Sec", ch->pcdata->security, fread_number(fp));	/* OLC */
-			KEY("Silv", ch->silver, fread_number(fp));
-			KEY("Shares", ch->pcdata->shares, fread_number(fp));
-			KEY("StrEdKey", ch->pcdata->str_ed_key, fread_letter(fp));
-			if (!str_cmp(word, "StayRace"))
-			{
-				ch->pcdata->stay_race = TRUE;
-				fMatch = TRUE;
-				break;
-			}
-
+			KEY("SavingThrow", ch->saving_throw, read_number(fp));
+			KEY("Save", ch->saving_throw, read_number(fp));
+			KEY("Scro", ch->lines, read_number(fp));
+			KEY("Sex", ch->sex, read_number(fp));
+			KEYS("ShortDescr", ch->short_descr);
+			KEYS("ShD", ch->short_descr);
+			KEY("Sec", ch->pcdata->security, read_number(fp));	/* OLC */
+			KEY("Silv", ch->silver, read_number(fp));
+			KEY("Shares", ch->pcdata->shares, read_number(fp));
+			KEY("StrEdKey", ch->pcdata->str_ed_key, read_letter(fp));
+			KEY_DO("StayRace", (ch->pcdata->stay_race = TRUE));
+			KEY_ARRAY("Stance", ch->stance, MAX_STANCE, 0);
 			if (!str_cmp(word, "Skill") || !str_cmp(word, "Sk"))
 			{
 				int sn;
 				int value;
 				char *temp;
 
-				value = fread_number(fp);
-				temp = fread_word(fp);
+				value = read_number(fp);
+				temp = read_word(fp);
 				sn = skill_lookup(temp);
-				/* sn    = skill_lookup( fread_word( fp ) ); */
+				/* sn    = skill_lookup( read_word( fp ) ); */
 				if (sn < 0)
 				{
-					bugf("Fread_char: unknown skill. (%s)", temp);
+					bugf("read_char: unknown skill. (%s)", temp);
 				}
 				else
 					ch->pcdata->learned[sn] = value;
 				fMatch = TRUE;
+				break;
 			}
 
 			break;
 
 		case 'T':
-			KEY("TrueSex", ch->pcdata->true_sex, fread_number(fp));
-			KEY("TSex", ch->pcdata->true_sex, fread_number(fp));
-			KEY("Trai", ch->train, fread_number(fp));
-			KEY("Trust", ch->trust, fread_number(fp));
-			KEY("Tru", ch->trust, fread_number(fp));
-			KEY("Trivia", ch->pcdata->trivia, fread_number(fp));
-			KEY("TimeZone", ch->pcdata->timezone, fread_number(fp));
+			KEY("TrueSex", ch->pcdata->true_sex, read_number(fp));
+			KEY("TSex", ch->pcdata->true_sex, read_number(fp));
+			KEY("Trai", ch->train, read_number(fp));
+			KEY("Trust", ch->trust, read_number(fp));
+			KEY("Tru", ch->trust, read_number(fp));
+			KEY("Trivia", ch->pcdata->trivia, read_number(fp));
+			KEY("TimeZone", ch->pcdata->timezone, read_number(fp));
 			if (!str_cmp(word, "Title") || !str_cmp(word, "Titl"))
 			{
-				ch->pcdata->title = fread_string(fp);
+				ch->pcdata->title = read_string(fp);
 				if (ch->pcdata->title[0] != '.' &&
 					ch->pcdata->title[0] != ',' &&
 					ch->pcdata->title[0] != '!' && ch->pcdata->title[0] != '?')
 				{
 					sprintf(buf, " %s", ch->pcdata->title);
-					free_string(ch->pcdata->title);
-					ch->pcdata->title = str_dup(buf);
+					replace_string(ch->pcdata->title, buf);
 				}
 				fMatch = TRUE;
 				break;
@@ -1315,44 +1230,39 @@
 			break;
 
 		case 'V':
-			KEY("Version", ch->version, fread_number(fp));
-			KEY("Vers", ch->version, fread_number(fp));
-			if (!str_cmp(word, "Vnum"))
-			{
-				ch->pIndexData = get_mob_index(fread_number(fp));
-				fMatch = TRUE;
-				break;
-			}
+			KEY("Version", ch->version, read_number(fp));
+			KEY("Vers", ch->version, read_number(fp));
+			KEY_DO("Vnum", (ch->pIndexData = get_mob_index(read_number(fp))));
 			break;
 
 		case 'W':
 			if (!str_cmp(word, "WarInfo"))
 			{
 				new_warlist(ch);
-				ch->war->hit = fread_number(fp);
-				ch->war->mana = fread_number(fp);
-				ch->war->move = fread_number(fp);
-				ch->war->flags = fread_flag(fp);
+				ch->war->hit = read_number(fp);
+				ch->war->mana = read_number(fp);
+				ch->war->move = read_number(fp);
+				ch->war->flags = read_flag(fp);
 				fMatch = TRUE;
 				break;
 			}
-			KEY("Wimpy", ch->wimpy, fread_number(fp));
-			KEY("Wimp", ch->wimpy, fread_number(fp));
-			KEY("Wizn", ch->wiznet, fread_flag(fp));
-			KEYS("WhoD", ch->pcdata->who_descr, fread_string(fp));
+			KEY("Wimpy", ch->wimpy, read_number(fp));
+			KEY("Wimp", ch->wimpy, read_number(fp));
+			KEY("Wizn", ch->wiznet, read_flag(fp));
+			KEYS("WhoD", ch->pcdata->who_descr);
 			break;
 		}
 
 		if (!fMatch)
 		{
-			bug("Fread_char: no match.", 0);
-			fread_to_eol(fp);
+			bugf("read_char: no match for %s->%s.", ch->name, word);
+			read_to_eol(fp);
 		}
 	}
 }
 
 /* load a pet from the forgotten reaches */
-void fread_pet(CHAR_DATA * ch, FILE * fp)
+void read_pet(CHAR_DATA * ch, READ_DATA * fp)
 {
 	const char *word;
 	CHAR_DATA *pet;
@@ -1361,15 +1271,15 @@
 	int percent;
 
 	/* first entry had BETTER be the vnum or we barf */
-	word = feof(fp) ? "END" : fread_word(fp);
+	word = steof(fp) ? "END" : read_word(fp);
 	if (!str_cmp(word, "Vnum"))
 	{
 		vnum_t vnum;
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (get_mob_index(vnum) == NULL)
 		{
-			bug("Fread_pet: bad vnum %d.", vnum);
+			bugf("Fread_pet: bad vnum %ld.", vnum);
 			pet = create_mobile(get_mob_index(MOB_VNUM_FIDO));
 		}
 		else
@@ -1377,33 +1287,39 @@
 	}
 	else
 	{
-		bug("Fread_pet: no vnum in file.", 0);
+		bug("Fread_pet: no vnum in file.");
 		pet = create_mobile(get_mob_index(MOB_VNUM_FIDO));
 	}
 
 	for (;;)
 	{
-		word = feof(fp) ? "END" : fread_word(fp);
+		word = steof(fp) ? "END" : read_word(fp);
 		fMatch = FALSE;
 
 		switch (UPPER(word[0]))
 		{
 		case '*':
 			fMatch = TRUE;
-			fread_to_eol(fp);
+			read_to_eol(fp);
 			break;
 
 		case 'A':
-			KEY("Act", pet->act, fread_flag(fp));
-			KEY("AfBy", pet->affected_by, fread_flag(fp));
-			KEY("Alig", pet->alignment, fread_number(fp));
+			KEY("Act", pet->act, read_flag(fp));
+			KEY("AfBy", pet->affected_by, read_flag(fp));
+			KEY("Alig", pet->alignment, read_number(fp));
 
 			if (!str_cmp(word, "ACs"))
 			{
-				int i;
+				if (pet->version < 9)
+				{
+					int i;
+
+					for (i = 0; i < 4; i++)
+						pet->armor[i] = read_number(fp);
+				}
+				else
+					read_array(pet->armor, 4, 100);
 
-				for (i = 0; i < 4; i++)
-					pet->armor[i] = fread_number(fp);
 				fMatch = TRUE;
 				break;
 			}
@@ -1415,17 +1331,17 @@
 
 				paf = new_affect();
 
-				sn = skill_lookup(fread_word(fp));
+				sn = skill_lookup(read_word(fp));
 				if (sn < 0)
-					bug("Fread_char: unknown skill.", 0);
+					bug("read_char: unknown skill.");
 				else
 					paf->type = sn;
 
-				paf->level = fread_number(fp);
-				paf->duration = fread_number(fp);
-				paf->modifier = fread_number(fp);
-				paf->location = fread_number(fp);
-				paf->bitvector = fread_number(fp);
+				paf->level = read_number(fp);
+				paf->duration = read_number(fp);
+				paf->modifier = read_number(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->bitvector = read_number(fp);
 				LINK(paf, pet->first_affect, pet->last_affect, next, prev);
 				fMatch = TRUE;
 				break;
@@ -1438,18 +1354,18 @@
 
 				paf = new_affect();
 
-				sn = skill_lookup(fread_word(fp));
+				sn = skill_lookup(read_word(fp));
 				if (sn < 0)
-					bug("Fread_char: unknown skill.", 0);
+					bug("read_char: unknown skill.");
 				else
 					paf->type = sn;
 
-				paf->where = fread_number(fp);
-				paf->level = fread_number(fp);
-				paf->duration = fread_number(fp);
-				paf->modifier = fread_number(fp);
-				paf->location = fread_number(fp);
-				paf->bitvector = fread_flag(fp);
+				paf->where = read_enum(where_t, fp);
+				paf->level = read_number(fp);
+				paf->duration = read_number(fp);
+				paf->modifier = read_number(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->bitvector = read_flag(fp);
 				LINK(paf, pet->first_affect, pet->last_affect, next, prev);
 				fMatch = TRUE;
 				break;
@@ -1457,40 +1373,43 @@
 
 			if (!str_cmp(word, "AMod"))
 			{
-				int stat;
+				if (pet->version < 9)
+				{
+					int stat;
 
-				for (stat = 0; stat < MAX_STATS; stat++)
-					pet->mod_stat[stat] = fread_number(fp);
+					for (stat = 0; stat < MAX_STATS; stat++)
+						pet->mod_stat[stat] = read_number(fp);
+				}
+				else
+					read_array(pet->mod_stat, MAX_STATS, 0);
 				fMatch = TRUE;
 				break;
 			}
 
 			if (!str_cmp(word, "Attr"))
 			{
-				int stat;
+				if (ch->version < 9)
+				{
+					int stat;
 
-				for (stat = 0; stat < MAX_STATS; stat++)
-					pet->perm_stat[stat] = fread_number(fp);
+					for (stat = 0; stat < MAX_STATS; stat++)
+						pet->perm_stat[stat] = read_number(fp);
+				}
+				else
+					read_array(pet->perm_stat, MAX_STATS, 3);
 				fMatch = TRUE;
 				break;
 			}
 			break;
 
 		case 'C':
-			if (!str_cmp(word, "Clan"))
-			{
-				const char *tmp = fread_string(fp);
-				pet->clan = clan_lookup(tmp);
-				free_string(tmp);
-				fMatch = TRUE;
-				break;
-			}
-			KEY("Comm", pet->comm, fread_flag(fp));
+			KEY_SFUN("Clan", pet->clan, clan_lookup);
+			KEY("Comm", pet->comm, read_flag(fp));
 			break;
 
 		case 'D':
-			KEY("Dam", pet->damroll, fread_number(fp));
-			KEYS("Desc", pet->description, fread_string(fp));
+			KEY("Dam", pet->damroll, read_number(fp));
+			KEYS("Desc", pet->description);
 			break;
 
 		case 'E':
@@ -1512,74 +1431,67 @@
 				}
 				return;
 			}
-			KEY("Exp", pet->exp, fread_number(fp));
+			KEY("Exp", pet->exp, read_number(fp));
 			break;
 
 		case 'G':
-			KEY("Gold", pet->gold, fread_number(fp));
+			KEY("Gold", pet->gold, read_number(fp));
 			break;
 
 		case 'H':
-			KEY("Hit", pet->hitroll, fread_number(fp));
+			KEY("Hit", pet->hitroll, read_number(fp));
 
 			if (!str_cmp(word, "HMV"))
 			{
-				pet->hit = fread_number(fp);
-				pet->max_hit = fread_number(fp);
-				pet->mana = fread_number(fp);
-				pet->max_mana = fread_number(fp);
-				pet->move = fread_number(fp);
-				pet->max_move = fread_number(fp);
+				pet->hit = read_number(fp);
+				pet->max_hit = read_number(fp);
+				pet->mana = read_number(fp);
+				pet->max_mana = read_number(fp);
+				pet->move = read_number(fp);
+				pet->max_move = read_number(fp);
 				fMatch = TRUE;
 				break;
 			}
 			break;
 
 		case 'L':
-			KEY("Levl", pet->level, fread_number(fp));
-			KEYS("LnD", pet->long_descr, fread_string(fp));
-			KEY("LogO", lastlogoff, fread_number(fp));
+			KEY("Levl", pet->level, read_number(fp));
+			KEYS("LnD", pet->long_descr);
+			KEY("LogO", lastlogoff, read_number(fp));
 			break;
 
 		case 'N':
-			KEYS("Name", pet->name, fread_string(fp));
+			KEYS("Name", pet->name);
 			break;
 
 		case 'P':
-			KEY("Pos", pet->position, fread_number(fp));
+			KEY("Pos", pet->position, read_enum(position_t, fp));
 			break;
 
 		case 'R':
-			if (!str_cmp(word, "Race"))
-			{
-				const char *tmp = fread_string(fp);
-				pet->race = race_lookup(tmp);
-				free_string(tmp);
-				fMatch = TRUE;
-				break;
-			}
+			KEY_SFUN("Race", pet->race, race_lookup);
 			break;
 
 		case 'S':
-			KEY("Save", pet->saving_throw, fread_number(fp));
-			KEY("Sex", pet->sex, fread_number(fp));
-			KEYS("ShD", pet->short_descr, fread_string(fp));
-			KEY("Silv", pet->silver, fread_number(fp));
+			KEY("Save", pet->saving_throw, read_number(fp));
+			KEY("Sex", pet->sex, read_number(fp));
+			KEYS("ShD", pet->short_descr);
+			KEY("Silv", pet->silver, read_number(fp));
 			break;
 
 			if (!fMatch)
 			{
-				bug("Fread_pet: no match.", 0);
-				fread_to_eol(fp);
+				bug("Fread_pet: no match.");
+				read_to_eol(fp);
 			}
 
 		}
 	}
 }
 
-extern OBJ_DATA *obj_free;
+EXTERN OBJ_DATA *obj_free;
 
-void fread_obj(CHAR_DATA * ch, FILE * fp, bool pit)
+void read_obj(CHAR_DATA * ch, READ_DATA * fp, bool pit)
 {
 	OBJ_DATA *obj;
 	const char *word;
@@ -1598,16 +1510,16 @@
 	new_format = FALSE;
 	make_new = FALSE;
 
-	word = feof(fp) ? "End" : fread_word(fp);
+	word = steof(fp) ? "End" : read_word(fp);
 	if (!str_cmp(word, "Vnum"))
 	{
 		vnum_t vnum;
 		first = FALSE;			/* fp will be in right place */
 
-		vnum = fread_number(fp);
+		vnum = read_number(fp);
 		if (get_obj_index(vnum) == NULL)
 		{
-			bug("Fread_obj: bad vnum %d.", vnum);
+			bugf("Fread_obj: bad vnum %ld.", vnum);
 		}
 		else
 		{
@@ -1636,14 +1548,14 @@
 		if (first)
 			first = FALSE;
 		else
-			word = feof(fp) ? "End" : fread_word(fp);
+			word = steof(fp) ? "End" : read_word(fp);
 		fMatch = FALSE;
 
 		switch (UPPER(word[0]))
 		{
 		case '*':
 			fMatch = TRUE;
-			fread_to_eol(fp);
+			read_to_eol(fp);
 			break;
 
 		case 'A':
@@ -1654,17 +1566,17 @@
 
 				paf = new_affect();
 
-				sn = skill_lookup(fread_word(fp));
+				sn = skill_lookup(read_word(fp));
 				if (sn < 0)
-					bug("Fread_obj: unknown skill.", 0);
+					bug("Fread_obj: unknown skill.");
 				else
 					paf->type = sn;
 
-				paf->level = fread_number(fp);
-				paf->duration = fread_number(fp);
-				paf->modifier = fread_number(fp);
-				paf->location = fread_number(fp);
-				paf->bitvector = fread_number(fp);
+				paf->level = read_number(fp);
+				paf->duration = read_number(fp);
+				paf->modifier = read_number(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->bitvector = read_number(fp);
 				LINK(paf, obj->first_affect, obj->last_affect, next, prev);
 				fMatch = TRUE;
 				break;
@@ -1676,18 +1588,18 @@
 
 				paf = new_affect();
 
-				sn = skill_lookup(fread_word(fp));
+				sn = skill_lookup(read_word(fp));
 				if (sn < 0)
-					bug("Fread_obj: unknown skill.", 0);
+					bug("Fread_obj: unknown skill.");
 				else
 					paf->type = sn;
 
-				paf->where = fread_number(fp);
-				paf->level = fread_number(fp);
-				paf->duration = fread_number(fp);
-				paf->modifier = fread_number(fp);
-				paf->location = fread_number(fp);
-				paf->bitvector = fread_flag(fp);
+				paf->where = read_enum(where_t, fp);
+				paf->level = read_number(fp);
+				paf->duration = read_number(fp);
+				paf->modifier = read_number(fp);
+				paf->location = read_enum(apply_t, fp);
+				paf->bitvector = read_flag(fp);
 				LINK(paf, obj->first_affect, obj->last_affect, next, prev);
 				fMatch = TRUE;
 				break;
@@ -1695,26 +1607,19 @@
 			break;
 
 		case 'C':
-			KEY("Cond", obj->condition, fread_number(fp));
-			KEY("Cost", obj->cost, fread_number(fp));
+			KEY("Cond", obj->condition, read_number(fp));
+			KEY("Cost", obj->cost, read_number(fp));
 			break;
 
 		case 'D':
-			KEYS("Description", obj->description, fread_string(fp));
-			KEYS("Desc", obj->description, fread_string(fp));
+			KEYS("Description", obj->description);
+			KEYS("Desc", obj->description);
 			break;
 
 		case 'E':
-
-			if (!str_cmp(word, "Enchanted"))
-			{
-				obj->enchanted = TRUE;
-				fMatch = TRUE;
-				break;
-			}
-
-			KEY("ExtraFlags", obj->extra_flags, fread_number(fp));
-			KEY("ExtF", obj->extra_flags, fread_flag(fp));
+			KEY_DO("Enchanted", (obj->enchanted = TRUE));
+			KEY("ExtraFlags", obj->extra_flags, read_number(fp));
+			KEY("ExtF", obj->extra_flags, read_flag(fp));
 
 			if (!str_cmp(word, "ExtraDescr") || !str_cmp(word, "ExDe"))
 			{
@@ -1722,8 +1627,8 @@
 
 				ed = new_extra_descr();
 
-				ed->keyword = fread_string(fp);
-				ed->description = fread_string(fp);
+				ed->keyword = read_string(fp);
+				ed->description = read_string(fp);
 				LINK(ed, obj->first_extra_descr, obj->last_extra_descr, next,
 					 prev);
 				fMatch = TRUE;
@@ -1733,7 +1638,7 @@
 			{
 				if (!fNest || (fVnum && obj->pIndexData == NULL))
 				{
-					bug("Fread_obj: incomplete object.", 0);
+					bug("Fread_obj: incomplete object.");
 					free_obj(obj);
 					return;
 				}
@@ -1759,7 +1664,7 @@
 					}
 					if (make_new)
 					{
-						int wear;
+						wloc_t wear;
 
 						wear = obj->wear_loc;
 						extract_obj(obj);
@@ -1804,24 +1709,24 @@
 			break;
 
 		case 'I':
-			KEY("ItemType", obj->item_type, fread_number(fp));
-			KEY("Ityp", obj->item_type, fread_number(fp));
+			KEY("ItemType", obj->item_type, read_number(fp));
+			KEY("Ityp", obj->item_type, read_number(fp));
 			break;
 
 		case 'L':
-			KEY("Level", obj->level, fread_number(fp));
-			KEY("Lev", obj->level, fread_number(fp));
+			KEY("Level", obj->level, read_number(fp));
+			KEY("Lev", obj->level, read_number(fp));
 			break;
 
 		case 'N':
-			KEYS("Name", obj->name, fread_string(fp));
+			KEYS("Name", obj->name);
 
 			if (!str_cmp(word, "Nest"))
 			{
-				iNest = fread_number(fp);
+				iNest = read_number(fp);
 				if (iNest < 0 || iNest >= MAX_NEST)
 				{
-					bug("Fread_obj: bad nest %d.", iNest);
+					bugf("Fread_obj: bad nest %d.", iNest);
 				}
 				else
 				{
@@ -1838,28 +1743,29 @@
 				if (obj->pIndexData != NULL && obj->pIndexData->new_format)
 					make_new = TRUE;
 				fMatch = TRUE;
+				break;
 			}
-			KEYS("Owner", obj->owner, fread_string(fp));
+			KEYS("Owner", obj->owner);
 			break;
 
 		case 'S':
-			KEYS("ShortDescr", obj->short_descr, fread_string(fp));
-			KEYS("ShD", obj->short_descr, fread_string(fp));
+			KEYS("ShortDescr", obj->short_descr);
+			KEYS("ShD", obj->short_descr);
 
 			if (!str_cmp(word, "Spell"))
 			{
 				int iValue;
 				int sn;
 
-				iValue = fread_number(fp);
-				sn = skill_lookup(fread_word(fp));
+				iValue = read_number(fp);
+				sn = skill_lookup(read_word(fp));
 				if (iValue < 0 || iValue > 3)
 				{
-					bug("Fread_obj: bad iValue %d.", iValue);
+					bugf("Fread_obj: bad iValue %d.", iValue);
 				}
 				else if (sn < 0)
 				{
-					bug("Fread_obj: unknown skill.", 0);
+					bug("Fread_obj: unknown skill.");
 				}
 				else
 				{
@@ -1872,17 +1778,17 @@
 			break;
 
 		case 'T':
-			KEY("Timer", obj->timer, fread_number(fp));
-			KEY("Time", obj->timer, fread_number(fp));
+			KEY("Timer", obj->timer, read_number(fp));
+			KEY("Time", obj->timer, read_number(fp));
 			break;
 
 		case 'V':
 			if (!str_cmp(word, "Values") || !str_cmp(word, "Vals"))
 			{
-				obj->value[0] = fread_number(fp);
-				obj->value[1] = fread_number(fp);
-				obj->value[2] = fread_number(fp);
-				obj->value[3] = fread_number(fp);
+				obj->value[0] = read_number(fp);
+				obj->value[1] = read_number(fp);
+				obj->value[2] = read_number(fp);
+				obj->value[3] = read_number(fp);
 				if (obj->item_type == ITEM_WEAPON && obj->value[0] == 0)
 					obj->value[0] = obj->pIndexData->value[0];
 				fMatch = TRUE;
@@ -1891,22 +1797,24 @@
 
 			if (!str_cmp(word, "Val"))
 			{
-				obj->value[0] = fread_number(fp);
-				obj->value[1] = fread_number(fp);
-				obj->value[2] = fread_number(fp);
-				obj->value[3] = fread_number(fp);
-				obj->value[4] = fread_number(fp);
+				obj->value[0] = read_number(fp);
+				obj->value[1] = read_number(fp);
+				obj->value[2] = read_number(fp);
+				obj->value[3] = read_number(fp);
+				obj->value[4] = read_number(fp);
 				fMatch = TRUE;
 				break;
 			}
 
+			KEY_ARRAY("Valu", obj->value, 5, 0);
+
 			if (!str_cmp(word, "Vnum"))
 			{
 				vnum_t vnum;
 
-				vnum = fread_number(fp);
+				vnum = read_number(fp);
 				if ((obj->pIndexData = get_obj_index(vnum)) == NULL)
-					bug("Fread_obj: bad vnum %d.", vnum);
+					bugf("Fread_obj: bad vnum %ld.", vnum);
 				else
 					fVnum = TRUE;
 				fMatch = TRUE;
@@ -1915,60 +1823,144 @@
 			break;
 
 		case 'W':
-			KEY("WearFlags", obj->wear_flags, fread_number(fp));
-			KEY("WeaF", obj->wear_flags, fread_flag(fp));
-			KEY("WearLoc", obj->wear_loc, fread_number(fp));
-			KEY("Wear", obj->wear_loc, fread_number(fp));
-			KEY("Weight", obj->weight, fread_number(fp));
-			KEY("Wt", obj->weight, fread_number(fp));
-			KEY("Where", where, fread_number(fp));
+			KEY("WearFlags", obj->wear_flags, read_number(fp));
+			KEY("WeaF", obj->wear_flags, read_flag(fp));
+			KEY("WearLoc", obj->wear_loc, read_enum(wloc_t, fp));
+			KEY("Wear", obj->wear_loc, read_enum(wloc_t, fp));
+			KEY("Weight", obj->weight, read_number(fp));
+			KEY("Wt", obj->weight, read_number(fp));
+			KEY("Where", where, read_number(fp));
 			break;
 
 		}
 
 		if (!fMatch)
 		{
-			bug("Fread_obj: no match.", 0);
-			fread_to_eol(fp);
+			bug("Fread_obj: no match.");
+			read_to_eol(fp);
 		}
 	}
 }
 
-CORPSE_DATA *corpse_first;
-CORPSE_DATA *corpse_last;
+void read_descriptor(DESCRIPTOR_DATA * d, READ_DATA * fp)
+{
+	const char *word;
+	bool fMatch;
+
+	for (;;)
+	{
+		word = steof(fp) ? "END" : read_word(fp);
+		fMatch = FALSE;
+		if (crs_info.status != CRS_COPYOVER_RECOVER)
+		{
+			if (!str_cmp(word, "End"))
+				return;
+			else
+			{
+				read_to_eol(fp);
+				continue;
+			}
+		}
+		switch (UPPER(word[0]))
+		{
+		case '*':
+			fMatch = TRUE;
+			read_to_eol(fp);
+			break;
+		case 'B':
+			KEY("ByteN", d->bytes_normal, read_number(fp));
+#if !defined(NO_MCCP)
+			KEY("ByteC", d->bytes_compressed, read_number(fp));
+#endif
+			break;
+		case 'C':
+			KEY("Connected", d->connected, read_enum(connect_t, fp));
+#if !defined(NO_MCCP)
+			KEY("CVersion", d->mccp_version, read_number(fp));
+#endif
+			break;
+		case 'D':
+			KEY("Descr", d->descriptor, read_number(fp));
+			break;
+		case 'E':
+			if (!str_cmp(word, "End"))
+				return;
+			break;
+		case 'F':
+			KEY("Flags", d->d_flags, read_flag(fp));
+			break;
+		case 'H':
+			KEYS("Host", d->host);
+			break;
+		case 'I':
+			KEY_DO("IMPver", d->imp_vers = atof(read_word(fp)));
+			break;
+		case 'K':
+			KEY("Keycode", d->portal.keycode, read_number(fp));
+			break;
+		case 'M':
+			KEYS("MXPSup", d->mxp.supports);
+			KEY_DO("MXPVer", d->mxp.mxp_ver = atof(read_word(fp)));
+			KEY_DO("MXPClVer", d->mxp.client_ver = atof(read_word(fp)));
+			KEY_DO("MXPStyl", d->mxp.style_ver = atof(read_word(fp)));
+			KEYS("MXPClien", d->mxp.client);
+			KEY("MXPReg", d->mxp.registered, read_number(fp));
+			KEY("MXPFlag1", d->mxp.flags, read_flag(fp));
+			KEY("MXPFlag2", d->mxp.flags2, read_flag(fp));
+			break;
+		case 'P':
+			KEYS_CPY("PortVer", d->portal.version);
+			KEY_DO("Pueblo", d->pueblo_vers = atof(read_word(fp)));
+			break;
+		case 'S':
+			KEY("ScrW", d->scr_width, read_number(fp));
+			KEY("ScrH", d->scr_height, read_number(fp));
+			break;
+		case 'T':
+			KEYS_CPY("TType", d->ttype);
+			break;
+		}
+
+		if (!fMatch)
+		{
+			bugf("no match for %s.", word);
+			read_to_eol(fp);
+		}
+	}
+}
 
 void save_corpses(void)
 {
-	FILE_DATA *fp;
+	WRITE_DATA *fp;
 	CORPSE_DATA *c;
 
-	if ((fp = fopen_temp(CORPSE_FILE)) == NULL)
+	if ((fp = open_write(CORPSE_FILE)) == NULL)
 	{
-		bug("save_corpses: " CORPSE_FILE " not found.", 0);
+		bug("save_corpses: " CORPSE_FILE " not found.");
 	}
 	else
 	{
 		for (c = corpse_first; c != NULL; c = c->next)
 		{
 			if (c->corpse->item_type == ITEM_CORPSE_PC)
-				fwrite_obj(NULL, c->corpse, fp->file, 0, "C");
+				fwrite_obj(NULL, c->corpse, fp->stream, 0, "C");
 			else
 				update_corpses(c->corpse, TRUE);
 		}
-		fprintf(fp->file, "#END\n");
-		fflush(fp->file);
-		fclose_temp(fp);
+		fprintf(fp->stream, "#END\n");
+		fflush(fp->stream);
+		close_write(fp);
 	}
 	return;
 }
 
 void load_corpses(void)
 {
-	FILE *fp;
+	READ_DATA *fp;
 
-	if ((fp = file_open(CORPSE_FILE, "r")) == NULL)
+	if ((fp = open_read(CORPSE_FILE)) == NULL)
 	{
-		bug("load_corpses: " CORPSE_FILE " not found", 0);
+		bug("load_corpses: " CORPSE_FILE " not found");
 	}
 	else
 	{
@@ -1977,34 +1969,32 @@
 			char letter;
 			char *word;
 
-			letter = fread_letter(fp);
+			letter = read_letter(fp);
 			if (letter == '*')
 			{
-				fread_to_eol(fp);
+				read_to_eol(fp);
 				continue;
 			}
 
 			if (letter != '#')
 			{
-				bug("load_corpses: # not found.", 0);
+				bug("load_corpses: # not found.");
 				break;
 			}
 
-			word = fread_word(fp);
+			word = read_word(fp);
 			if ((!str_cmp(word, "CORPSE")) || (!str_cmp(word, "C")))
-				fread_obj(NULL, fp, FALSE);
+				read_obj(NULL, fp, FALSE);
 			else if (!str_cmp(word, "END"))
 				break;
 			else
 			{
-				bug("load_corpses: bad section.", 0);
+				bug("load_corpses: bad section.");
 				break;
 			}
 		}
+		close_read(fp);
 	}
-
-	file_close(fp);
-
 	return;
 }
 
Only in new: save.h
diff -ur -x config -x o -x rom src/scan.c new/scan.c
--- src/scan.c	Tue May 27 02:46:36 2003
+++ new/scan.c	Sun Aug 31 19:23:21 2003
@@ -22,15 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 
@@ -39,9 +34,9 @@
 	"off in the distance %s."
 };
 
-void scan_list
-args((ROOM_INDEX_DATA * scan_room, CHAR_DATA * ch, int depth, int door));
-void scan_char args((CHAR_DATA * victim, CHAR_DATA * ch, int depth, int door));
+PROTOTYPE(void scan_list, (ROOM_INDEX_DATA *, CHAR_DATA *, int, int));
+PROTOTYPE(void scan_char, (CHAR_DATA *, CHAR_DATA *, int, int));
+
 CH_CMD(do_scan)
 {
 	char arg1[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH];
@@ -51,7 +46,7 @@
 
 	argument = one_argument(argument, arg1);
 
-	if (arg1[0] == '\0')
+	if (IS_NULLSTR(arg1))
 	{
 		act("$n looks all around.", ch, NULL, NULL, TO_ROOM);
 		chprintln(ch, "Looking around you see:");
Only in new: sendstat.c
Only in new: signals.c
Only in new: signals.h
diff -ur -x config -x o -x rom src/skills.c new/skills.c
--- src/skills.c	Tue May 27 02:46:36 2003
+++ new/skills.c	Sun Aug 31 19:23:21 2003
@@ -22,17 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <sys/time.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include "merc.h"
 #include "interp.h"
 #include "magic.h"
@@ -63,7 +56,7 @@
 
 	one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		do_function(trainer, &do_say, "Pardon me?");
 		return;
@@ -255,7 +248,7 @@
 	if (IS_NPC(ch))
 		return;
 
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		fAll = TRUE;
 
@@ -276,7 +269,7 @@
 				return;
 			}
 
-			if (argument[0] != '\0')
+			if (!IS_NULLSTR(argument))
 			{
 				argument = one_argument(argument, arg);
 				if (!is_number(arg))
@@ -355,9 +348,9 @@
 	buffer = new_buf();
 	for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
 		if (spell_list[level][0] != '\0')
-			add_buf(buffer, spell_list[level]);
-	add_buf(buffer, "\n\r");
-	page_to_char(buf_string(buffer), ch);
+			bprint(buffer, spell_list[level]);
+	bprintln(buffer, "");
+	sendpage(ch, buf_string(buffer));
 	free_buf(buffer);
 }
 
@@ -374,7 +367,7 @@
 	if (IS_NPC(ch))
 		return;
 
-	if (argument[0] != '\0')
+	if (!IS_NULLSTR(argument))
 	{
 		fAll = TRUE;
 
@@ -395,7 +388,7 @@
 				return;
 			}
 
-			if (argument[0] != '\0')
+			if (!IS_NULLSTR(argument))
 			{
 				argument = one_argument(argument, arg);
 				if (!is_number(arg))
@@ -470,9 +463,9 @@
 	buffer = new_buf();
 	for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
 		if (skill_list[level][0] != '\0')
-			add_buf(buffer, skill_list[level]);
-	add_buf(buffer, "\n\r");
-	page_to_char(buf_string(buffer), ch);
+			bprint(buffer, skill_list[level]);
+	bprintln(buffer, "");
+	sendpage(ch, buf_string(buffer));
 	free_buf(buffer);
 }
 
@@ -541,8 +534,6 @@
 	return;
 }
 
-void list_group_chosen(CHAR_DATA * ch);
-
 void list_group_chosen(CHAR_DATA * ch)
 {
 	char buf[100];
@@ -643,14 +634,14 @@
 	char arg[MAX_INPUT_LENGTH];
 	int gn, sn, i;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 		return FALSE;
 
 	argument = one_argument(argument, arg);
 
 	if (!str_prefix(arg, "help"))
 	{
-		if (argument[0] == '\0')
+		if (IS_NULLSTR(argument))
 		{
 			do_function(ch, &do_oldhelp, "group help");
 			return TRUE;
@@ -662,7 +653,7 @@
 
 	if (!str_prefix(arg, "add"))
 	{
-		if (argument[0] == '\0')
+		if (IS_NULLSTR(argument))
 		{
 			chprintln(ch, "You must provide a skill name.");
 			return TRUE;
@@ -734,7 +725,7 @@
 
 	if (!str_cmp(arg, "drop"))
 	{
-		if (argument[0] == '\0')
+		if (IS_NULLSTR(argument))
 		{
 			chprintln(ch, "You must provide a skill to drop.");
 			return TRUE;
@@ -809,7 +800,7 @@
 
 	col = 0;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{							/* show all groups */
 
 		for (gn = 0; gn < maxGroup; gn++)
@@ -1089,10 +1080,10 @@
 		for (level = 0; level < MAX_MORTAL_LEVEL + 1; level++)
 		{
 			if (!IS_NULLSTR(skill_list[level]))
-				add_buf(buffer, skill_list[level]);
+				bprint(buffer, skill_list[level]);
 		}
-		add_buf(buffer, "\n\r");
-		page_to_char(buf_string(buffer), ch);
+		bprintln(buffer, "");
+		sendpage(ch, buf_string(buffer));
 		free_buf(buffer);
 		return;
 	}
diff -ur -x config -x o -x rom src/special.c new/special.c
--- src/special.c	Tue May 27 02:46:36 2003
+++ new/special.c	Sun Aug 31 19:23:21 2003
@@ -22,16 +22,10 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "magic.h"
@@ -410,8 +404,6 @@
 /*
  * Core procedure for dragons.
  */
-bool dragon(CHAR_DATA * ch, char *spell_name);
-
 bool dragon(CHAR_DATA * ch, char *spell_name)
 {
 	CHAR_DATA *victim;
diff -ur -x config -x o -x rom src/spells.h new/spells.h
--- src/spells.h	Tue May 27 02:46:36 2003
+++ new/spells.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 #if defined(MAGIC_FUN)
diff -ur -x config -x o -x rom src/statlist.c new/statlist.c
--- src/statlist.c	Tue May 27 02:46:36 2003
+++ new/statlist.c	Sun Aug 31 19:23:21 2003
@@ -22,19 +22,29 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#if !defined(WIN32)
-#include <unistd.h>
-#endif
 #include "merc.h"
 #include "interp.h"
 #include "recycle.h"
+#include "tablesave.h"
+
+STAT_DATA xStat;
+
+const struct savetable_type statsavetable[] = {
+	{"name", FIELD_STRING, (void *) &xStat.name, NULL, NULL},
+
+	{"stats", FIELD_LONG_ARRAY, (void *) &xStat.gamestat,
+	 (const void *) MAX_GAMESTAT, (const void *) 0},
+	{NULL, 0, NULL, NULL, NULL}
+};
+
+TABLESAVE(rw_stats)
+{
+	rw_list(type, STAT_FILE, STAT_DATA, stat_first, stat_last, next, prev,
+			new_stat_data, "STAT", xStat, statsavetable);
+}
 
 void update_statlist(CHAR_DATA * ch, bool pdelete)
 {
@@ -55,7 +65,7 @@
 		{
 			UNLINK(curr, stat_first, stat_last, next, prev);
 			free_stat_data(curr);
-			save_statlist();
+			rw_stats(action_write);
 		}
 	}
 	if (pdelete)
@@ -66,10 +76,10 @@
 	curr = new_stat_data();
 	curr->name = str_dup(ch->name);
 	for (i = 0; i < MAX_GAMESTAT; i++)
-		curr->gamestat[i] = ch->pcdata->gamestat[i];
+		curr->gamestat[i] = GET_STAT(ch, i);
 
 	LINK(curr, stat_first, stat_last, next, prev);
-	save_statlist();
+	rw_stats(action_write);
 	return;
 }
 
@@ -80,7 +90,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "      {ROPTIONS AVAILABLE:{x");
 		chprintln(ch, "      {G1{x - Ranking of Player Killers (pkills)");
@@ -107,7 +117,7 @@
 			{
 				UNLINK(curr, stat_first, stat_last, next, prev);
 				free_stat_data(curr);
-				save_statlist();
+				rw_stats(action_write);
 				found = TRUE;
 			}
 		}
@@ -158,7 +168,6 @@
 {
 	STAT_DATA *curr;
 	BUFFER *output;
-	char buf[MSL];
 	STAT_DATA **top;
 	int count, pos, loop;
 	bool found = FALSE;
@@ -177,9 +186,7 @@
 
 	alloc_mem(top, STAT_DATA *, topstat);
 
-	sprintf(buf, "{CRANKING OF %s{x", stat_name[type]);
-	add_buf(output, buf);
-	add_buf(output, "\n\r");
+	bprintlnf(output, "{CRANKING OF %s{x", stat_name[type]);
 	loop = 0;
 	loop = 0;
 	for (curr = stat_first; curr != NULL; curr = curr->next)
@@ -198,21 +205,20 @@
 			if (loop >= 50)
 				break;
 
-			sprintf(buf, "{G%2d{w){W %-20s {w[{R%8ld{W]{x    ",
+			bprintf(output, "{G%2d{w){W %-20s {w[{R%8ld{W]{x    ",
 					loop + 1, top[loop]->name, top[loop]->gamestat[type]);
-			add_buf(output, buf);
 			if (++pos % 2 == 0)
 			{
-				add_buf(output, "\n\r");
+				bprintln(output, "");
 				pos = 0;
 			}
 		}
 	}
 	if (!found)
-		add_buf(output, "\n\rNo one found yet.\n\r");
+		bprintln(output, "\n\rNo one found yet.");
 	else if (pos % 2 != 0)
-		add_buf(output, "\n\r");
-	page_to_char(buf_string(output), ch);
+		bprintln(output, "");
+	sendpage(ch, buf_string(output));
 	free_mem(top);
 	free_buf(output);
 	return;
diff -ur -x config -x o -x rom src/string.c new/string.c
--- src/string.c	Tue May 27 02:46:36 2003
+++ new/string.c	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /***************************************************************************
@@ -38,23 +38,13 @@
  *                                                                         *
  ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "tables.h"
 #include "olc.h"
-#if defined(WIN32)
-#include "../win32/winstuff.h"
-#endif
-
-const char *string_linedel(const char *, int);
-const char *string_lineadd(const char *, const char *, int);
-const char *numlineas(const char *);
+
+PROTOTYPE(const char *string_linedel, (const char *, int));
+PROTOTYPE(const char *string_lineadd, (const char *, const char *, int));
+PROTOTYPE(const char *numlineas, (const char *));
 
 /*****************************************************************************
  Name:		string_edit
@@ -236,7 +226,7 @@
 		break;
 	case PARSE_EDIT:
 		string = one_argument(string, arg1);
-		if (arg1[0] == '\0')
+		if (IS_NULLSTR(arg1))
 		{
 			chprintln(ch, "You must specify a line number.");
 			return;
@@ -246,18 +236,24 @@
 		chprintln(ch, "Line replaced.");
 		break;
 	case PARSE_DELETE:
-		if (string[0] == '\0')
+		if (IS_NULLSTR(string))
+		{
 			*text = del_last_line(*text);
+			chprintln(ch, "Last line deleted.");
+		}
 		else
+		{
 			*text = string_linedel(*text, atoi(string));
-		chprintln(ch, "Line deleted.");
+			chprintlnf(ch, "Line %d deleted.", atoi(string));
+		}
 		break;
 	case PARSE_REPLACE:
 		string = first_arg(string, arg1, FALSE);
 		string = first_arg(string, arg2, FALSE);
-		if (arg1[0] == '\0')
+		if (IS_NULLSTR(arg1))
 		{
-			chprintln(ch, "Usage: .r 'old string' 'new string'");
+			chprintlnf(ch, "Usage: %cr 'old string' 'new string'",
+					   STR_EDIT_KEY(ch));
 			return;
 		}
 		*text = string_replace(*text, arg1, arg2);
@@ -266,9 +262,10 @@
 	case PARSE_REPLACE_ALL:
 		string = first_arg(string, arg1, FALSE);
 		string = first_arg(string, arg2, FALSE);
-		if (arg1[0] == '\0')
+		if (IS_NULLSTR(arg1))
 		{
-			chprintln(ch, "Usage: .R 'old string' 'new string'");
+			chprintlnf(ch, "Usage: %cR 'old string' 'new string'",
+					   STR_EDIT_KEY(ch));
 			return;
 		}
 		*text = string_replace_all(*text, arg1, arg2);
@@ -278,24 +275,25 @@
 	case PARSE_INSERT:
 		string = first_arg(string, arg1, FALSE);
 		*text = string_lineadd(*text, string, atoi(arg1));
-		chprintln(ch, "Line inserted.");
+		chprintlnf(ch, "Line %d inserted.", atoi(arg1));
 		break;
 	case PARSE_LIST_NORM:
 		chprintln(ch, "String so far:");
-		page_to_char(*text, ch);
+		sendpage(ch, *text);
 		break;
 	case PARSE_LIST_NUM:
 		chprintln(ch, "String so far:");
-		page_to_char(numlineas(*text), ch);
+		sendpage(ch, numlineas(*text));
 		break;
 	default:
 		chprintln(ch, "Invalid command.");
-		bug("invalid command passed", 0);
+		bug("invalid command passed");
 		break;
 	}
 }
 
-int parse_string_command(const char **text, const char *str, CHAR_DATA * ch)
+strshow_t parse_string_command(const char **text, const char *str,
+							   CHAR_DATA * ch)
 {
 	int i = 2, j = 0;
 	char actions[MAX_INPUT_LENGTH];
@@ -366,7 +364,7 @@
 void string_add(CHAR_DATA * ch, char *argument)
 {
 	char buf[MSL];
-	int action = 0;
+	strshow_t action;
 
 	action = parse_string_command(ch->desc->pString, argument, ch);
 
@@ -459,8 +457,7 @@
 		smash_tilde(argument);
 		strcat(buf, argument);
 		strcat(buf, "\n\r");
-		free_string(*ch->desc->pString);
-		*ch->desc->pString = str_dup(buf);
+		replace_string(*ch->desc->pString, buf);
 		return;
 	}
 }
@@ -609,7 +606,7 @@
 		}
 		else
 		{
-			bug("No spaces", 0);
+			bug("No spaces");
 			*(char *) (rdesc + 75) = 0;
 			strcat(xbuf, rdesc);
 			strcat(xbuf, "-\n\r");
@@ -821,9 +818,6 @@
 	return str_dup(buf);
 }
 
-/* buf queda con la linea sin \n\r */
-const char *getline(const char *str, char *buf);
-
 const char *getline(const char *str, char *buf)
 {
 	int tmp = 0;
@@ -1040,10 +1034,7 @@
 
 	if (length <= 0)
 	{
-		if (!ch || !ch->desc)
-			length = 79;
-		else
-			length = ch->desc->scr_width - 1;
+		length = get_scr_cols(ch);
 	}
 
 	while (*count_string && nCount != length)
@@ -1177,7 +1168,7 @@
 {
 	unsigned int i;
 
-	if (string[0] == '\0')
+	if (IS_NULLSTR(string))
 	{
 		return FALSE;
 	}
@@ -1241,10 +1232,7 @@
 
 	if (len <= 0)
 	{
-		if (!ch || !ch->desc)
-			len = 79;
-		else
-			len = ch->desc->scr_width - 1;
+		len = get_scr_cols(ch);
 	}
 	mod = len % strlen_color(fill);
 	len /= strlen_color(fill);
@@ -1333,6 +1321,9 @@
 	static int i;
 	static char buf[10][MSL * 3];
 	va_list args;
+
+	if (IS_NULLSTR(formatbuf))
+		return "";
 
 	++i;
 	i %= 10;
Only in new: structs.h
diff -ur -x config -x o -x rom src/tables.c new/tables.c
--- src/tables.c	Tue May 27 02:46:36 2003
+++ new/tables.c	Sun Aug 31 19:23:21 2003
@@ -22,12 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <stdio.h>
-#include <time.h>
 #include "merc.h"
 #include "tables.h"
 #include "interp.h"
@@ -114,8 +111,7 @@
 	{"killer", PLR_KILLER, FALSE},
 	{"questor", PLR_QUESTOR, TRUE},
 	{"autodamage", PLR_AUTODAMAGE, TRUE},
-	{"challenged", PLR_CHALLENGED, TRUE},
-	{"challenger", PLR_CHALLENGER, TRUE},
+	{"autoprompt", PLR_AUTOPROMPT, TRUE},
 	{NULL, 0, 0}
 };
 
@@ -297,6 +293,13 @@
 	{"eor", DESC_TELOPT_EOR, TRUE},
 	{"echo", DESC_TELOPT_ECHO, TRUE},
 	{"naws", DESC_TELOPT_NAWS, TRUE},
+	{"pueblo", DESC_PUEBLO, TRUE},
+	{"mxp", DESC_MXP, TRUE},
+	{"msp", DESC_MSP, TRUE},
+	{"ttype", DESC_TELOPT_TTYPE, TRUE},
+	{"binary", DESC_TELOPT_BINARY, TRUE},
+	{"portal", DESC_PORTAL, TRUE},
+	{"imp", DESC_IMP, TRUE},
 	{NULL, 0, 0}
 };
 
@@ -993,4 +996,44 @@
 	{"GMT+10", "Sydney, Melbourne, Guam", 10, 0},
 	{"GMT+11", "Magadan, Soloman Is.", 11, 0},
 	{"GMT+12", "Fiji, Wellington, Auckland", 12, 0}
+};
+
+const struct flag_type chan_types[] = {
+	{"public", spec_public_flag, TRUE},
+	{"clan", spec_clan_flag, TRUE},
+	{"immortal", spec_imm_flag, TRUE},
+	{"buddy", spec_buddy_flag, TRUE},
+	{"none", spec_none, FALSE},
+	{NULL, 0, 0}
+};
+
+const struct flag_type mud_flags[] = {
+	{"wizlock", MUD_WIZLOCK, TRUE},
+	{"newlock", MUD_NEWLOCK, TRUE},
+	{"logall", MUD_LOGALL, TRUE},
+	{"nodnslookups", NO_DNS_LOOKUPS, TRUE},
+	{NULL, 0, 0}
+};
+
+const struct flag_type ignore_flags[] = {
+	{"none", 0, TRUE},
+	{"channels", IGNORE_CHANNELS, TRUE},
+	{"notes", IGNORE_NOTES, TRUE},
+	{"tells", IGNORE_TELLS, TRUE},
+	{"announce", IGNORE_ANNOUNCE, TRUE},
+	{"levels", IGNORE_LEVELS, TRUE},
+	{"socials", IGNORE_SOCIALS, TRUE},
+	{"all", IGNORE_ALL, TRUE},
+	{"says", IGNORE_SAY, TRUE},
+	{NULL, 0, FALSE}
+};
+
+const struct directory_type directories_table[] = {
+	{"Player files.", PLAYER_DIR},
+	{"Data files.", DATA_DIR},
+	{"Area files.", AREA_DIR},
+	{"Binary files.", BIN_DIR},
+	{"Log files.", LOG_DIR},
+	{"Note files.", NOTE_DIR},
+	{NULL, NULL}
 };
diff -ur -x config -x o -x rom src/tables.h new/tables.h
--- src/tables.h	Tue May 27 02:46:36 2003
+++ new/tables.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
@@ -30,58 +30,63 @@
 #define TABLES_H
 
 /* game tables */
-extern const struct position_type position_table[];
-extern const struct sex_type sex_table[];
-extern const struct size_type size_table[];
+EXTERN const struct position_type position_table[];
+EXTERN const struct sex_type sex_table[];
+EXTERN const struct size_type size_table[];
 
 /* flag tables */
-extern const struct flag_type act_flags[];
-extern const struct flag_type plr_flags[];
-extern const struct flag_type affect_flags[];
-extern const struct flag_type off_flags[];
-extern const struct flag_type imm_flags[];
-extern const struct flag_type form_flags[];
-extern const struct flag_type part_flags[];
-extern const struct flag_type comm_flags[];
-extern const struct flag_type extra_flags[];
-extern const struct flag_type wear_flags[];
-extern const struct flag_type container_flags[];
-extern const struct flag_type portal_flags[];
-extern const struct flag_type room_flags[];
-extern const struct flag_type exit_flags[];
-extern const struct flag_type mprog_flags[];
-extern const struct flag_type oprog_flags[];
-extern const struct flag_type rprog_flags[];
-extern const struct flag_type area_flags[];
-extern const struct flag_type sector_flags[];
-extern const struct flag_type door_resets[];
-extern const struct flag_type wear_loc_strings[];
-extern const struct flag_type wear_loc_flags[];
-extern const struct flag_type res_flags[];
-extern const struct flag_type vuln_flags[];
-extern const struct flag_type type_flags[];
-extern const struct flag_type apply_flags[];
-extern const struct flag_type sex_flags[];
-extern const struct flag_type furniture_flags[];
-extern const struct flag_type weapon_class[];
-extern const struct flag_type apply_types[];
-extern const struct flag_type weapon_type2[];
-extern const struct flag_type size_flags[];
-extern const struct flag_type position_flags[];
-extern const struct flag_type ac_type[];
-extern const struct bit_type bitvector_type[];
-extern const struct colour_type colour_attributes[];
-extern const struct colour_type colour_foregrounds[];
-extern const struct colour_type colour_backgrounds[];
-extern const struct cslot_type cslot_table[MAX_CUSTOM_COLOUR];
-extern const struct flag_type desc_flags[];
-extern const struct vnum_type vnum_table[];
-extern const struct flag_type info_flags[];
-extern const struct flag_type log_flags[];
-extern const struct spfun_type spell_table[];
-extern const struct gsn_type gsn_table[];
-extern const struct flag_type target_flags[];
-extern const struct tzone_type tzone_table[MAX_TZONE];
+EXTERN const struct flag_type act_flags[];
+EXTERN const struct flag_type plr_flags[];
+EXTERN const struct flag_type affect_flags[];
+EXTERN const struct flag_type off_flags[];
+EXTERN const struct flag_type imm_flags[];
+EXTERN const struct flag_type form_flags[];
+EXTERN const struct flag_type part_flags[];
+EXTERN const struct flag_type comm_flags[];
+EXTERN const struct flag_type extra_flags[];
+EXTERN const struct flag_type wear_flags[];
+EXTERN const struct flag_type container_flags[];
+EXTERN const struct flag_type portal_flags[];
+EXTERN const struct flag_type room_flags[];
+EXTERN const struct flag_type exit_flags[];
+EXTERN const struct flag_type mprog_flags[];
+EXTERN const struct flag_type oprog_flags[];
+EXTERN const struct flag_type rprog_flags[];
+EXTERN const struct flag_type area_flags[];
+EXTERN const struct flag_type sector_flags[];
+EXTERN const struct flag_type door_resets[];
+EXTERN const struct flag_type wear_loc_strings[];
+EXTERN const struct flag_type wear_loc_flags[];
+EXTERN const struct flag_type res_flags[];
+EXTERN const struct flag_type vuln_flags[];
+EXTERN const struct flag_type type_flags[];
+EXTERN const struct flag_type apply_flags[];
+EXTERN const struct flag_type sex_flags[];
+EXTERN const struct flag_type furniture_flags[];
+EXTERN const struct flag_type weapon_class[];
+EXTERN const struct flag_type apply_types[];
+EXTERN const struct flag_type weapon_type2[];
+EXTERN const struct flag_type size_flags[];
+EXTERN const struct flag_type position_flags[];
+EXTERN const struct flag_type ac_type[];
+EXTERN const struct bit_type bitvector_type[];
+EXTERN const struct colour_type colour_attributes[];
+EXTERN const struct colour_type colour_foregrounds[];
+EXTERN const struct colour_type colour_backgrounds[];
+EXTERN const struct cslot_type cslot_table[MAX_CUSTOM_COLOUR];
+EXTERN const struct flag_type desc_flags[];
+EXTERN const struct vnum_type vnum_table[];
+EXTERN const struct flag_type info_flags[];
+EXTERN const struct flag_type log_flags[];
+EXTERN const struct spfun_type spell_table[];
+EXTERN const struct gsn_type gsn_table[];
+EXTERN const struct flag_type target_flags[];
+EXTERN const struct flag_type chan_types[];
+EXTERN const struct tzone_type tzone_table[MAX_TZONE];
+EXTERN const struct flag_type mud_flags[];
+EXTERN const struct flag_type ignore_flags[];
+EXTERN const struct directory_type directories_table[];
+EXTERN const struct flag_stat_type flag_stat_table[];
 
 struct flag_type
 {
@@ -90,6 +95,13 @@
 	bool settable;
 };
 
+struct flag_stat_type
+{
+	const char *name;
+	const struct flag_type *structure;
+	bool stat;
+};
+
 struct clan_rank
 {
 	const char *rankname;
@@ -169,19 +181,23 @@
 	int *pgsn;
 };
 
+struct directory_type
+{
+	const char *text;
+	const char *directory;
+};
+
 /* vnum types */
 #define VNUM_OBJ    1
 #define VNUM_ROOM   2
 #define VNUM_MOB    3
 #define VNUM_MPROG  4
 
-flag_t flag_value
-args((const struct flag_type * flag_table, const char *argument));
-const struct flag_type *flag_lookup
-args((const char *name, const struct flag_type * f));
-const char *flag_string
-args((const struct flag_type * flag_table, flag_t bits));
-void show_flag_cmds(CHAR_DATA * ch, const struct flag_type *flag_table);
-bool is_stat(const struct flag_type *flag_table);
+PROTOTYPE(flag_t flag_value, (const struct flag_type *, const char *));
+PROTOTYPE(const struct flag_type *flag_lookup,
+		  (const char *, const struct flag_type *));
+PROTOTYPE(const char *flag_string, (const struct flag_type *, flag_t));
+PROTOTYPE(void show_flag_cmds, (CHAR_DATA *, const struct flag_type *));
+PROTOTYPE(bool is_stat, (const struct flag_type *));
 
 #endif
diff -ur -x config -x o -x rom src/tablesave.c new/tablesave.c
--- src/tablesave.c	Tue May 27 02:46:36 2003
+++ new/tablesave.c	Sun Aug 31 19:23:21 2003
@@ -22,15 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "tables.h"
 #include "lookup.h"
@@ -38,36 +32,9 @@
 #include "olc.h"
 #include "recycle.h"
 #include "db.h"
-
-struct savetable_type
-{
-	char *field;
-	int type_field;
-	void *puntero_field;
-	const void *argument;
-	const void *argument2;
-};
-
-#define FIELD_STRING			0
-#define FIELD_FUNCION_INT_TO_STR	1
-#define FIELD_LONG_ARRAY        2
-#define FIELD_FLAGSTRING		3
-#define FIELD_INT			4
-#define FIELD_FLAGVECTOR		5
-#define FIELD_BOOL			6
-#define FIELD_INT_ARRAY		7
-#define FIELD_STRING_ARRAY		8
-#define FIELD_INT_FLAGSTRING    9
-#define FIELD_BOOL_ARRAY		10
-#define FIELD_INUTIL			11
-#define FIELD_INT_ALLOC_ARRAY   12
-#define FIELD_LONG              13
-#define FIELD_STRING_ARRAY_NULL 14
-#define FIELD_RANK              15
-#define FIELD_LONG_ALLOC_ARRAY  16
-
-typedef char *STR_FUNC(void *);
-typedef bool STR_READ_FUNC(void *, const char *);
+#include "music.h"
+#include "tablesave.h"
+#include "save.h"
 
 CMD_DATA cmd;
 SKILL_DATA sk;
@@ -75,158 +42,238 @@
 GROUP_DATA grp;
 CLASS_DATA cls;
 SOCIAL_DATA soc;
-CLAN_DATA clan;
-STAT_DATA stat;
-BAN_DATA ban;
 GQUEST gq;
 DEITY_DATA deity;
-WPWD_DATA pwd;
-MBR_DATA mbr;
-WAR_DATA war;
-
-const char *do_fun_name(DO_FUN *);
-DO_FUN *do_fun_lookup(const char *);
+WAR war;
+CHANNEL_DATA cd;
+MUD mud;
+SONG_DATA song;
 
-const char *skill_gsn_name(int *);
-int *gsn_lookup(const char *);
+PROTOTYPE(const char *do_fun_name, (DO_FUN *));
+PROTOTYPE(DO_FUN * do_fun_lookup, (const char *));
 
-const char *spell_fun_name(SPELL_FUN *);
-SPELL_FUN *spell_lookup(const char *);
+PROTOTYPE(const char *skill_gsn_name, (int *));
+PROTOTYPE(int *gsn_lookup, (const char *));
 
-const char *do_fun_str(void *temp)
-{
-	DO_FUN **fun = (DO_FUN **) temp;
+PROTOTYPE(const char *spell_fun_name, (SPELL_FUN *));
+PROTOTYPE(SPELL_FUN * spell_lookup, (const char *));
 
-	return do_fun_name(*fun);
-}
+PROTOTYPE(const char *gcn_name, (int *));
+PROTOTYPE(int *gcn_lookup, (const char *));
 
-const char *position_str(void *temp)
+RW_FUN(pgcn_rw)
 {
-	int *flags = (int *) temp;
+	int **pgcn = (int **) temp;
 
-	return position_table[*flags].name;
-}
+	switch (type)
+	{
+	case action_read:
+		{
+			int *blah = gcn_lookup(*arg);
 
-const char *size_str(void *temp)
-{
-	int *size = (int *) temp;
+			*pgcn = blah;
 
-	return size_table[UMAX(0, *size)].name;
+			return *pgcn != NULL;
+		}
+	case action_write:
+		{
+			*arg = gcn_name(*pgcn);
+			return *pgcn != NULL;
+		}
+	default:
+		return FALSE;
+	}
 }
 
-const char *race_str(void *temp)
+RW_FUN(do_fun_rw)
 {
-	RACE_DATA **raza = (RACE_DATA **) temp;
-	RACE_DATA *tmp;
-
-	for (tmp = race_first; tmp; tmp = tmp->next)
-		if (tmp == *raza)
-			return tmp->name;
+	DO_FUN **fun = (DO_FUN **) temp;
 
-	return "unique";
+	switch (type)
+	{
+	case action_write:
+		*arg = do_fun_name(*fun);
+		return TRUE;
+	case action_read:
+		*fun = do_fun_lookup(*arg);
+		return TRUE;
+	default:
+		return FALSE;
+	}
 }
 
-const char *pgsn_str(void *temp)
+RW_FUN(position_rw)
 {
-	int **pgsn = (int **) temp;
+	position_t *pos = (position_t *) temp;
 
-	return skill_gsn_name(*pgsn);
-}
+	switch (type)
+	{
+	case action_read:
+		{
+			position_t ffg = position_lookup(*arg);
 
-const char *spell_fun_str(void *temp)
-{
-	SPELL_FUN **spfun = (SPELL_FUN **) temp;
+			*pos = UMAX(POS_NONE, ffg);
 
-	return spell_fun_name(*spfun);
+			return (ffg != -1);
+		}
+	case action_write:
+		{
+			*arg = position_table[UMAX(0, *pos)].name;
+			return (*pos != -1);
+		}
+	default:
+		return FALSE;
+	}
 }
 
-bool do_fun_read(void *temp, char *arg)
+RW_FUN(size_rw)
 {
-	DO_FUN **fun = (DO_FUN **) temp;
+	int *size = (int *) temp;
+
+	switch (type)
+	{
+	case action_read:
+		{
+			int ffg = size_lookup(*arg);
 
-	*fun = do_fun_lookup(arg);
+			*size = UMAX(0, ffg);
 
-	return TRUE;
+			return (ffg != -1);
+		}
+	case action_write:
+		{
+			*arg = size_table[UMAX(0, *size)].name;
+			return (*size != -1);
+		}
+	default:
+		return FALSE;
+	}
 }
 
-bool position_read(void *temp, char *arg)
+RW_FUN(sex_rw)
 {
-	int *posic = (int *) temp;
-	int ffg = position_lookup(arg);
+	int *sex = (int *) temp;
 
-	*posic = UMAX(0, ffg);
+	switch (type)
+	{
+	case action_read:
+		{
+			int ffg = sex_lookup(*arg);
+
+			*sex = UMAX(0, ffg);
 
-	if (ffg == -1)
+			return (ffg != -1);
+		}
+	case action_write:
+		{
+			*arg = sex_table[UMAX(0, *sex)].name;
+			return (*sex != -1);
+		}
+	default:
 		return FALSE;
-	else
-		return TRUE;
+	}
 }
 
-bool size_read(void *temp, char *arg)
+RW_FUN(attack_rw)
 {
-	int *size = (int *) temp;
-	int ffg = size_lookup(arg);
+	int *r = (int *) temp;
+	switch (type)
+	{
+	case action_read:
+		{
+			int ffg = attack_lookup(*arg);
 
-	*size = UMAX(0, ffg);
+			*r = UMAX(0, ffg);
 
-	if (ffg == -1)
+			return (ffg != -1);
+		}
+	case action_write:
+		{
+			*arg = attack_table[UMAX(0, *r)].name;
+			return (*r != -1);
+		}
+	default:
 		return FALSE;
-	else
-		return TRUE;
+	}
 }
 
-bool pgsn_read(void *temp, char *arg)
+RW_FUN(pgsn_rw)
 {
 	int **pgsn = (int **) temp;
-	int *blah = gsn_lookup(arg);
 
-	*pgsn = blah;
+	switch (type)
+	{
+	case action_read:
+		{
+			int *blah = gsn_lookup(*arg);
 
-	return !str_cmp(arg, "") || blah != NULL;
+			*pgsn = blah;
+
+			return *pgsn != NULL;
+		}
+	case action_write:
+		{
+			*arg = skill_gsn_name(*pgsn);
+			return *pgsn != NULL;
+		}
+	default:
+		return FALSE;
+	}
 }
 
-bool spell_fun_read(void *temp, char *arg)
+RW_FUN(spell_fun_rw)
 {
 	SPELL_FUN **spfun = (SPELL_FUN **) temp;
-	SPELL_FUN *blah = spell_lookup(arg);
 
-	*spfun = blah;
-
-	return !str_cmp(arg, "") || blah != NULL;
-}
-
-const char *clan_str(void *temp)
-{
-	CLAN_DATA **clan = (CLAN_DATA **) temp;
-	CLAN_DATA *tmp;
+	switch (type)
+	{
+	case action_read:
+		{
+			SPELL_FUN *blah = spell_lookup(*arg);
 
-	for (tmp = clan_first; tmp; tmp = tmp->next)
-		if (tmp == *clan)
-			return tmp->name;
+			*spfun = blah;
 
-	return "unknown";
+			return *spfun != NULL;
+		}
+	case action_write:
+		{
+			*arg = spell_fun_name(*spfun);
+			return *spfun != NULL;
+		}
+	default:
+		return FALSE;
+	}
 }
 
-bool clan_read(void *temp, char *arg)
+RW_FUN(clan_rw)
 {
-	CLAN_DATA **posic = (CLAN_DATA **) temp;
+	CLAN_DATA **c = (CLAN_DATA **) temp;
 
-	*posic = clan_lookup(arg);
+	switch (type)
+	{
+	case action_read:
+		{
+			*c = clan_lookup(*arg);
 
-	if (*posic == NULL)
+			return *c != NULL;
+		}
+	case action_write:
+		{
+			*arg = *c == NULL ? "unknown" : (*c)->name;
+			return *c != NULL;
+		}
+	default:
 		return FALSE;
-	else
-		return TRUE;
+	}
 }
 
 const struct savetable_type cmdsavetable[] = {
 	{"name", FIELD_STRING, (void *) &cmd.name, NULL, NULL},
 
-	{"do_fun", FIELD_FUNCION_INT_TO_STR, (void *) &cmd.do_fun,
-	 (const void *) do_fun_str,
-	 (const void *) do_fun_read},
-	{"position", FIELD_FUNCION_INT_TO_STR, (void *) &cmd.position,
-	 (const void *) position_str, (const void *) position_read},
+	{"do_fun", FIELD_FUNCTION_INT_TO_STR, (void *) &cmd.do_fun,
+	 (const void *) do_fun_rw, NULL},
+	{"position", FIELD_FUNCTION_INT_TO_STR, (void *) &cmd.position,
+	 (const void *) position_rw, NULL},
 	{"level", FIELD_INT, (void *) &cmd.level, NULL, NULL},
 
 	{"log", FIELD_FLAGSTRING, (void *) &cmd.log, (const void *) log_flags,
@@ -242,19 +289,18 @@
 	 (const void *) &maxClass, (const void *) (LEVEL_IMMORTAL + 1)},
 	{"ratings", FIELD_INT_ALLOC_ARRAY, (void *) &sk.rating,
 	 (const void *) &maxClass, (const void *) 0},
-	{"spell_fun", FIELD_FUNCION_INT_TO_STR, (void *) &sk.spell_fun,
-	 (const void *) spell_fun_str, (const void *) spell_fun_read},
+	{"spell_fun", FIELD_FUNCTION_INT_TO_STR, (void *) &sk.spell_fun,
+	 (const void *) spell_fun_rw, NULL},
 
 	{"target", FIELD_INT_FLAGSTRING, (void *) &sk.target,
 	 (const void *) target_flags, NULL},
 
-	{"minimum_position", FIELD_FUNCION_INT_TO_STR,
+	{"minimum_position", FIELD_FUNCTION_INT_TO_STR,
 
-	 (void *) &sk.minimum_position, (const void *) position_str,
-	 (const void *) position_read},
-	{"pgsn", FIELD_FUNCION_INT_TO_STR, (void *) &sk.pgsn,
-	 (const void *) pgsn_str,
-	 (const void *) pgsn_read},
+	 (void *) &sk.minimum_position, (const void *) position_rw,
+	 NULL},
+	{"pgsn", FIELD_FUNCTION_INT_TO_STR, (void *) &sk.pgsn,
+	 (const void *) pgsn_rw, NULL},
 	{"min_mana", FIELD_INT, (void *) &sk.min_mana, NULL, NULL},
 	{"beats", FIELD_INT, (void *) &sk.beats, NULL, NULL},
 	{"noun_damage", FIELD_STRING, (void *) &sk.noun_damage, NULL, NULL},
@@ -287,9 +333,8 @@
 	{"mstats", FIELD_INT_ARRAY, (void *) &race.max_stats,
 	 (const void *) MAX_STATS, (const void *) 25},
 
-	{"size", FIELD_FUNCION_INT_TO_STR, (void *) &race.size,
-	 (const void *) size_str,
-	 (const void *) size_read},
+	{"size", FIELD_FUNCTION_INT_TO_STR, (void *) &race.size,
+	 (const void *) size_rw, NULL},
 	{NULL, 0, NULL, NULL, NULL}
 };
 
@@ -333,30 +378,6 @@
 	{NULL, 0, NULL, NULL, NULL}
 };
 
-const struct savetable_type clansavetable[] = {
-	{"name", FIELD_STRING, (void *) &clan.name, NULL, NULL},
-	{"whoname", FIELD_STRING, (void *) &clan.who_name, NULL, NULL},
-	{"hall", FIELD_LONG, (void *) &clan.hall, NULL, NULL},
-	{"indep", FIELD_BOOL, (void *) &clan.independent, NULL, NULL},
-	{"rank", FIELD_RANK, (void *) &clan.rank, (void *) MAX_RANK, NULL},
-	{NULL, 0, NULL, NULL, NULL}
-};
-
-const struct savetable_type statsavetable[] = {
-	{"name", FIELD_STRING, (void *) &stat.name, NULL, NULL},
-
-	{"stats", FIELD_LONG_ARRAY, (void *) &stat.gamestat,
-	 (const void *) MAX_GAMESTAT, (const void *) 0},
-	{NULL, 0, NULL, NULL, NULL}
-};
-
-const struct savetable_type bansavetable[] = {
-	{"name", FIELD_STRING, (void *) &ban.name, NULL, NULL},
-	{"level", FIELD_INT, (void *) &ban.level, NULL, NULL},
-	{"flags", FIELD_FLAGVECTOR, (void *) &ban.ban_flags, NULL, NULL},
-	{NULL, 0, NULL, NULL, NULL}
-};
-
 const struct savetable_type gqsavetable[] = {
 
 	{"mcount", FIELD_INT, (void *) &gq.mob_count, NULL, NULL},
@@ -380,21 +401,6 @@
 	{NULL, 0, NULL, NULL, NULL}
 };
 
-const struct savetable_type pwdsavetable[] = {
-	{"name", FIELD_STRING, (void *) &pwd.name, NULL, NULL},
-	{"pwd", FIELD_STRING, (void *) &pwd.passw, NULL, NULL},
-	{NULL, 0, NULL, NULL, NULL}
-};
-
-const struct savetable_type mbrsavetable[] = {
-	{"name", FIELD_STRING, (void *) &mbr.name, NULL, NULL},
-	{"clan", FIELD_FUNCION_INT_TO_STR, (void *) &mbr.clan, (void *) clan_str,
-	 (void *) clan_read},
-	{"rank", FIELD_INT, (void *) &mbr.rank, NULL, NULL},
-	{"level", FIELD_INT, (void *) &mbr.level, NULL, NULL},
-	{NULL, 0, NULL, NULL, NULL}
-};
-
 const struct savetable_type warsavetable[] = {
 	{"who", FIELD_STRING, (void *) &war.who, NULL, NULL},
 	{"minlvl", FIELD_INT, (void *) &war.min_level, NULL, NULL},
@@ -406,7 +412,44 @@
 	{NULL, 0, NULL, NULL, NULL}
 };
 
-void load_struct(FILE * fp, void *typebase,
+const struct savetable_type chansavetable[] = {
+	{"pgcn", FIELD_FUNCTION_INT_TO_STR, (void *) &cd.index, (void *) pgcn_rw,
+	 NULL},
+	{"colour", FIELD_STRING, (void *) &cd.colour, NULL, NULL},
+	{"customc", FIELD_INT, (void *) &cd.custom_colour, NULL, NULL},
+	{"format", FIELD_STRING, (void *) &cd.format, NULL, NULL},
+	{"bit", FIELD_FLAGSTRING, (void *) &cd.bit, (void *) comm_flags, NULL},
+	{"specflag", FIELD_INT, (void *) &cd.spec_flag, NULL, NULL},
+	{"length", FIELD_INT, (void *) &cd.page_length, NULL, NULL},
+	{"name", FIELD_STRING, (void *) &cd.name, NULL, NULL},
+	{"desc", FIELD_STRING, (void *) &cd.description, NULL, NULL},
+	{NULL, 0, NULL, NULL, NULL}
+};
+
+const struct savetable_type mudsavetable[] = {
+	{"mud_flags", FIELD_FLAGVECTOR, (void *) &mud.mud_flags, NULL, NULL},
+	{"pulse_second", FIELD_INT, (void *) &mud.pulsepersec, NULL, NULL},
+	{"arena", FIELD_INT, (void *) &mud.arena, NULL, NULL},
+	{"share_value", FIELD_INT, (void *) &mud.share_value, NULL, NULL},
+	{"rand_factor", FIELD_INT, (void *) &mud.rand_factor, NULL, NULL},
+	{"weath_unit", FIELD_INT, (void *) &mud.weath_unit, NULL, NULL},
+	{"max_vector", FIELD_INT, (void *) &mud.max_vector, NULL, NULL},
+	{"climate_factor", FIELD_INT, (void *) &mud.climate_factor, NULL, NULL},
+	{"max_online", FIELD_INT, (void *) &mud.max_online, NULL, NULL},
+	{NULL, 0, NULL, NULL, NULL}
+};
+
+const struct savetable_type songsavetable[] = {
+	{"name", FIELD_STRING, (void *) &song.name, NULL, NULL},
+	{"group", FIELD_STRING, (void *) &song.group, NULL, NULL},
+	{"lines", FIELD_INT, (void *) &song.lines, NULL, NULL},
+
+	{"lyrics", FIELD_STRING_ARRAY_NULL, (void *) &song.lyrics,
+	 (void *) MAX_LINES, NULL},
+	{NULL, 0, NULL, NULL, NULL}
+};
+
+void load_struct(READ_DATA * fp, void *typebase,
 				 const struct savetable_type *table, void *puntero)
 {
 	const char *word;
@@ -418,7 +461,7 @@
 	int **array;
 	long *plong;
 	long **larray;
-	STR_READ_FUNC *function;
+	RW_FUNC *function;
 	struct flag_type *flagtable;
 	bool found = FALSE;
 	bool *pbool;
@@ -426,7 +469,7 @@
 	RANK_DATA *rdata;
 	flag_t ftemp;
 
-	while (str_cmp((word = fread_word(fp)), "#END"))
+	while (str_cmp((word = read_word(fp)), "#END"))
 	{
 		for (temp = table; !IS_NULLSTR(temp->field); temp++)
 		{
@@ -438,7 +481,7 @@
 					pstring =
 						(const char **) ((int) temp->puntero_field -
 										 (int) typebase + (int) puntero);
-					*pstring = fread_string(fp);
+					*pstring = read_string(fp);
 					found = TRUE, cnt++;
 					break;
 
@@ -446,7 +489,7 @@
 					pint =
 						(int *) ((int) temp->puntero_field - (int) typebase +
 								 (int) puntero);
-					*pint = fread_number(fp);
+					*pint = read_number(fp);
 					found = TRUE, cnt++;
 					break;
 
@@ -454,17 +497,17 @@
 					plong =
 						(long *) ((int) temp->puntero_field - (int) typebase +
 								  (int) puntero);
-					*plong = fread_number(fp);
+					*plong = read_number(fp);
 					found = TRUE, cnt++;
 					break;
 
-				case FIELD_FUNCION_INT_TO_STR:
-					function = (STR_READ_FUNC *) temp->argument2;
-					string = fread_string(fp);
+				case FIELD_FUNCTION_INT_TO_STR:
+					function = (RW_FUNC *) temp->argument;
+					string = read_string(fp);
 					pint =
 						(int *) ((int) temp->puntero_field - (int) typebase +
 								 (int) puntero);
-					if ((*function) (pint, string) == FALSE)
+					if ((*function) (action_read, pint, &string) == FALSE)
 						bugf("field %s invalid, string %s",
 							 temp->field, string);
 					free_string(string);
@@ -476,7 +519,7 @@
 					pentero =
 						(flag_t *) ((int) temp->puntero_field -
 									(int) typebase + (int) puntero);
-					string = fread_string(fp);
+					string = read_string(fp);
 					ftemp = flag_value(flagtable, string);
 					*pentero = UMAX(0, ftemp);
 					free_string(string);
@@ -488,7 +531,7 @@
 					pint =
 						(int *) ((int) temp->puntero_field - (int) typebase +
 								 (int) puntero);
-					string = fread_string(fp);
+					string = read_string(fp);
 					ftemp = flag_value(flagtable, string);
 					*pint = UMAX(0, ftemp);
 					free_string(string);
@@ -499,7 +542,7 @@
 					pentero =
 						(flag_t *) ((int) temp->puntero_field -
 									(int) typebase + (int) puntero);
-					*pentero = fread_flag(fp);
+					*pentero = read_flag(fp);
 					found = TRUE, cnt++;
 					break;
 
@@ -507,7 +550,7 @@
 					pbool =
 						(bool *) ((int) temp->puntero_field - (int) typebase +
 								  (int) puntero);
-					string = fread_word(fp);
+					string = read_word(fp);
 					*pbool = str_cmp(string, "FALSE") ? TRUE : FALSE;
 					found = TRUE, cnt++;
 					break;
@@ -517,7 +560,7 @@
 						(int *) ((int) temp->puntero_field - (int) typebase +
 								 (int) puntero);
 					i = 0;
-					while (str_cmp((string = fread_word(fp)), "@"))
+					while (str_cmp((string = read_word(fp)), "@"))
 					{
 						if (i == (int) temp->argument)
 							bugf("field_shint_array %s has excess elements",
@@ -526,7 +569,7 @@
 							pint[i++] = (int) atoi(string);
 					}
 					while (i < (int) temp->argument)
-						pint[i++] = (int) temp->argument2;
+						pint[i++] = (int) temp->array_arg;
 					found = TRUE, cnt++;
 					break;
 
@@ -536,7 +579,7 @@
 								  (int) puntero);
 					i = 0;
 					alloc_mem(*array, int, *(int *) temp->argument);
-					while (str_cmp((string = fread_word(fp)), "@"))
+					while (str_cmp((string = read_word(fp)), "@"))
 					{
 						if (i == *(int *) temp->argument)
 							bugf("field_shint_array %s has excess elements",
@@ -545,7 +588,7 @@
 							(*array)[i++] = (int) atoi(string);
 					}
 					while (i < *(int *) temp->argument)
-						(*array)[i++] = (int) temp->argument2;
+						(*array)[i++] = (int) temp->array_arg;
 					found = TRUE, cnt++;
 					break;
 
@@ -554,7 +597,7 @@
 						(long *) ((int) temp->puntero_field - (int) typebase +
 								  (int) puntero);
 					i = 0;
-					while (str_cmp((string = fread_word(fp)), "@"))
+					while (str_cmp((string = read_word(fp)), "@"))
 					{
 						if (i == (int) temp->argument)
 							bugf("field_shint_array %s has excess elements",
@@ -563,7 +606,7 @@
 							plong[i++] = (long) atol(string);
 					}
 					while (i < (int) temp->argument)
-						plong[i++] = (long) temp->argument2;
+						plong[i++] = (long) temp->array_arg;
 					found = TRUE, cnt++;
 					break;
 
@@ -573,7 +616,7 @@
 								   (int) puntero);
 					i = 0;
 					alloc_mem(*larray, long, *(int *) temp->argument);
-					while (str_cmp((string = fread_word(fp)), "@"))
+					while (str_cmp((string = read_word(fp)), "@"))
 					{
 						if (i == *(int *) temp->argument)
 							bugf("field_shint_array %s has excess elements",
@@ -582,7 +625,7 @@
 							(*larray)[i++] = (long) atol(string);
 					}
 					while (i < *(int *) temp->argument)
-						(*larray)[i++] = (long) temp->argument2;
+						(*larray)[i++] = (long) temp->array_arg;
 					found = TRUE, cnt++;
 					break;
 
@@ -592,7 +635,7 @@
 						(const char **) ((int) temp->puntero_field -
 										 (int) typebase + (int) puntero);
 					i = 0;
-					while (str_cmp((string = fread_string(fp)), "@"))
+					while (str_cmp((string = read_string(fp)), "@"))
 					{
 						if (i == (int) temp->argument)
 							bugf("field_string_array %s has excess elements.",
@@ -605,18 +648,18 @@
 					found = TRUE, cnt++;
 					break;
 
-				case FIELD_RANK:
+				case FIELD_RANK_DATA:
 					rdata =
 						(RANK_DATA *) ((int) temp->puntero_field -
 									   (int) typebase + (int) puntero);
-					i = fread_number(fp);
-					//fread_string(fp);
-					rdata[i - 1].rankname = fread_string(fp);
+					i = read_number(fp);
+					//read_string(fp);
+					rdata[i - 1].rankname = read_string(fp);
 					found = TRUE, cnt++;
 					break;
 
 				case FIELD_INUTIL:
-					fread_to_eol(fp);
+					read_to_eol(fp);
 					found = TRUE, cnt++;
 					break;
 
@@ -625,13 +668,9 @@
 						(bool *) ((int) temp->puntero_field - (int) typebase +
 								  (int) puntero);
 					i = 0;
-					while (str_cmp((string = fread_word(fp)), "@"))
+					while (str_cmp((string = read_word(fp)), "@"))
 					{
-						if ((temp->argument != NULL
-							 && i == (int) temp->argument)
-							|| (temp->argument == NULL
-								&& temp->argument2 != NULL
-								&& i == *((int *) temp->argument2)))
+						if (temp->argument != NULL && i == (int) temp->argument)
 							bugf("field_bool_array %s has excess elements",
 								 temp->field);
 						else
@@ -648,7 +687,7 @@
 		if (found == FALSE)
 		{
 			bugf("word %s not found", word);
-			fread_to_eol(fp);
+			read_to_eol(fp);
 		}
 		else
 			found = FALSE;
@@ -664,7 +703,7 @@
 	long *plong;
 	int **array;
 	long **larray;
-	STR_FUNC *function;
+	RW_FUNC *function;
 	const char *string;
 	flag_t *pentero;
 	bool *pbool;
@@ -685,7 +724,8 @@
 			pstring =
 				(const char **) ((int) temp->puntero_field - (int) typebase +
 								 (int) puntero);
-			fprintf(fp, "%s\t\t%s~\n", temp->field,
+			fprintf(fp, "%s%s%s~\n", temp->field,
+					format_tabs(strlen(temp->field)),
 					IS_NULLSTR(*pstring) ? "" : fix_string(*pstring));
 			break;
 
@@ -693,23 +733,27 @@
 			pint =
 				(int *) ((int) temp->puntero_field - (int) typebase +
 						 (int) puntero);
-			fprintf(fp, "%s\t\t%d\n", temp->field, *pint);
+			fprintf(fp, "%s%s%d\n", temp->field,
+					format_tabs(strlen(temp->field)), *pint);
 			break;
 
 		case FIELD_LONG:
 			plong =
 				(long *) ((int) temp->puntero_field - (int) typebase +
 						  (int) puntero);
-			fprintf(fp, "%s\t\t%ld\n", temp->field, *plong);
+			fprintf(fp, "%s%s%ld\n", temp->field,
+					format_tabs(strlen(temp->field)), *plong);
 			break;
 
-		case FIELD_FUNCION_INT_TO_STR:
-			function = (STR_FUNC *) temp->argument;
+		case FIELD_FUNCTION_INT_TO_STR:
+			function = (RW_FUNC *) temp->argument;
 			pint =
 				(int *) ((int) temp->puntero_field - (int) typebase +
 						 (int) puntero);
-			string = (*function) ((void *) pint);
-			fprintf(fp, "%s\t\t%s~\n", temp->field, string);
+			if ((*function) (action_write, (void *) pint, &string) == FALSE)
+				bugf("field %s invalid, string %s", temp->field, string);
+			fprintf(fp, "%s%s%s~\n", temp->field,
+					format_tabs(strlen(temp->field)), string);
 			break;
 
 		case FIELD_FLAGSTRING:
@@ -717,8 +761,9 @@
 			pentero =
 				(flag_t *) ((int) temp->puntero_field - (int) typebase +
 							(int) puntero);
-			fprintf(fp, "%s\t\t%s~\n", temp->field,
-					flag_string(flagtable, *pentero));
+			fprintf(fp, "%s%s%s~\n", temp->field,
+					format_tabs(strlen(temp->field)), flag_string(flagtable,
+																  *pentero));
 			break;
 
 		case FIELD_INT_FLAGSTRING:
@@ -726,22 +771,25 @@
 			pint =
 				(int *) ((int) temp->puntero_field - (int) typebase +
 						 (int) puntero);
-			fprintf(fp, "%s\t\t%s~\n", temp->field,
-					flag_string(flagtable, *pint));
+			fprintf(fp, "%s%s%s~\n", temp->field,
+					format_tabs(strlen(temp->field)), flag_string(flagtable,
+																  *pint));
 			break;
 
 		case FIELD_FLAGVECTOR:
 			pentero =
 				(flag_t *) ((int) temp->puntero_field - (int) typebase +
 							(int) puntero);
-			fprintf(fp, "%s\t\t%s\n", temp->field, fwrite_flags(*pentero));
+			fprintf(fp, "%s%s%s\n", temp->field,
+					format_tabs(strlen(temp->field)), fwrite_flags(*pentero));
 			break;
 
 		case FIELD_BOOL:
 			pbool =
 				(bool *) ((int) temp->puntero_field - (int) typebase +
 						  (int) puntero);
-			fprintf(fp, "%s\t\t%s\n", temp->field,
+			fprintf(fp, "%s%s%s\n", temp->field,
+					format_tabs(strlen(temp->field)),
 					(*pbool == TRUE) ? "TRUE" : "FALSE");
 			break;
 
@@ -813,15 +861,12 @@
 				(bool *) ((int) temp->puntero_field - (int) typebase +
 						  (int) puntero);
 			fprintf(fp, "%s\t\t", temp->field);
-			for (i = 0;
-				 i <
-				 (temp->argument ? (int) temp->argument : *(int *) temp->
-				  argument2); i++)
+			for (i = 0; i < (int) temp->argument; i++)
 				fprintf(fp, "%d ", pbool[i] == TRUE ? 1 : 0);
 			fprintf(fp, "@\n");
 			break;
 
-		case FIELD_RANK:
+		case FIELD_RANK_DATA:
 			rdata =
 				(RANK_DATA *) ((int) temp->puntero_field - (int) typebase +
 							   (int) puntero);
@@ -841,885 +886,127 @@
 	}
 };
 
-void save_commands(void)
-{
-	FILE_DATA *fp;
-	CMD_DATA *i;
-
-	fp = fopen_temp(COMMAND_FILE);
-
-	if (!fp)
-	{
-		perror("save_commands");
-		return;
-	}
-
-	for (i = cmd_first; i; i = i->next)
-	{
-		fprintf(fp->file, "#COMMAND\n");
-		save_struct(fp->file, &cmd, cmdsavetable, i);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n\n");
-
-	fclose_temp(fp);
-}
-
-void load_commands(void)
-{
-	FILE *fp;
-	static CMD_DATA emptycmd;
-	CMD_DATA *i;
-	const char *word;
-
-	fp = file_open(COMMAND_FILE, "r");
-
-	if (fp == NULL)
-	{
-		perror("load_commands ");
-		file_close(fp);
-		return;
-	}
-
-	while (TRUE)
-	{
-		word = feof(fp) ? "#!" : fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#COMMAND"))
-		{
-			bugf("word %s", word);
-			file_close(fp);
-			return;
-		}
-
-		i = new_command();
-		*i = emptycmd;
-		load_struct(fp, &cmd, cmdsavetable, i);
-		add_command(i);
-	}
-}
-
-void save_skills(void)
-{
-	FILE_DATA *fp;
-	int i;
-
-	fp = fopen_temp(SKILL_FILE);
-
-	if (!fp)
-	{
-		bug("save_skills: NULL fp", 0);
-		return;
-	}
-
-	fprintf(fp->file, "%d\n", maxSkill);
-
-	for (i = 0; i < maxSkill; ++i)
-	{
-		fprintf(fp->file, "#SKILL\n");
-		save_struct(fp->file, &sk, skillsavetable, &skill_table[i]);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
-}
-
-void load_skills(void)
-{
-	FILE *fp;
-	static SKILL_DATA skzero;
-	int i = 0;
-	const char *word;
-
-	fp = file_open(SKILL_FILE, "r");
-
-	if (!fp)
-	{
-		bug("load_skills: Unable to open " SKILL_FILE " to load skills.", 0);
-		exit(1);
-	}
-
-	fscanf(fp, "%d\n", &maxSkill);
-
-	alloc_mem(skill_table, SKILL_DATA, maxSkill + 1);
-
-	if (!skill_table)
-	{
-		bugf("Error! Skill_table == NULL, MAX_SKILL : %d", maxSkill);
-		exit(1);
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#SKILL"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		if (i >= maxSkill)
-		{
-			bug("load_skills: number greater than maxSkill", 0);
-			exit(1);
-		}
-
-		skill_table[i] = skzero;
-		load_struct(fp, &sk, skillsavetable, &skill_table[i++]);
-	}
-
-	skill_table[maxSkill].name = NULL;
-
-	file_close(fp);
-}
-
-void save_races(void)
-{
-	FILE_DATA *fp;
-	RACE_DATA *temp;
-
-	fp = fopen_temp(RACE_FILE);
-
-	if (!fp)
-	{
-		perror("save_races : fopen");
-		return;
-	}
-
-	for (temp = race_first; temp; temp = temp->next)
-	{
-		fprintf(fp->file, "#RACE\n");
-		save_struct(fp->file, &race, racesavetable, temp);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n\n");
-
-	fclose_temp(fp);
-}
-
-void load_races(void)
-{
-	FILE *fp;
-	const char *word;
-	RACE_DATA *pRace;
-
-	fp = file_open(RACE_FILE, "r");
-
-	if (!fp)
-	{
-		perror("load_races");
-		return;
-	}
-
-	while (TRUE)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#RACE"))
-		{
-			bugf("word %s", word);
-			file_close(fp);
-			return;
-		}
-
-		pRace = new_race();
-		load_struct(fp, &race, racesavetable, pRace);
-		LINK(pRace, race_first, race_last, next, prev);
-	}
-}
-
-void save_groups(void)
-{
-	FILE_DATA *fp;
-	int i;
-
-	fp = fopen_temp(GROUP_FILE);
-
-	if (!fp)
-	{
-		bug("save_groups: NULL fp", 0);
-		return;
-	}
-
-	fprintf(fp->file, "%d\n", maxGroup);
-
-	for (i = 0; i < maxGroup; ++i)
-	{
-		fprintf(fp->file, "#GROUP\n");
-		save_struct(fp->file, &grp, groupsavetable, &group_table[i]);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
-}
-
-void load_groups(void)
-{
-	FILE *fp;
-	static GROUP_DATA grpzero;
-	int i = 0;
-	const char *word;
-
-	fp = file_open(GROUP_FILE, "r");
-
-	if (!fp)
-	{
-		bug("load_groups: Unable to open " GROUP_FILE " to load groups.", 0);
-		exit(1);
-	}
-
-	fscanf(fp, "%d\n", &maxGroup);
-
-	alloc_mem(group_table, GROUP_DATA, maxGroup + 1);
-
-	if (!group_table)
-	{
-		bugf("Error! Group_table == NULL, MAX_GROUP : %d", maxGroup);
-		exit(1);
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#GROUP"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		if (i >= maxGroup)
-		{
-			bug("load_groups: number greater than maxGroup", 0);
-			exit(1);
-		}
-
-		group_table[i] = grpzero;
-		load_struct(fp, &grp, groupsavetable, &group_table[i++]);
-	}
-
-	group_table[maxGroup].name = NULL;
-
-	file_close(fp);
-}
+const struct data_save_type data_save_table[] = {
+	{rw_commands, "commands"},
+	{rw_skills, "skills"},
+	{rw_races, "races"},
+	{rw_groups, "groups"},
+	{rw_classes, "classes"},
+	{rw_socials, "socials"},
+	{rw_clans, "clans"},
+	{rw_stats, "stats"},
+	{rw_bans, "bans"},
+	{rw_gquest_data, "gquest"},
+	{rw_deities, "deities"},
+	{rw_webpasswds, "webpasswds"},
+	{rw_members, "members"},
+	{rw_war_data, "war"},
+	{rw_channels, "channels"},
+	{rw_mud_data, "mud"},
+	{rw_music, "music"},
+	{NULL, NULL}
+};
 
-void save_classes(void)
+TABLESAVE(rw_commands)
 {
-	FILE_DATA *fp;
-	int i;
-
-	fp = fopen_temp(CLASS_FILE);
-
-	if (!fp)
-	{
-		bug("save_classes: NULL fp", 0);
-		return;
-	}
-
-	fprintf(fp->file, "%d\n", maxClass);
-
-	for (i = 0; i < maxClass; ++i)
-	{
-		fprintf(fp->file, "#CLASS\n");
-		save_struct(fp->file, &cls, classsavetable, &class_table[i]);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
+	rw_list(type, COMMAND_FILE, CMD_DATA, cmd_first, cmd_last, next, prev,
+			new_command, "COMMAND", cmd, cmdsavetable);
 }
 
-void load_classes(void)
+TABLESAVE(rw_skills)
 {
-	FILE *fp;
-	static CLASS_DATA clszero;
-	int i = 0;
-	const char *word;
-
-	fp = file_open(CLASS_FILE, "r");
-
-	if (!fp)
-	{
-		bug("load_classes: Unable to open " CLASS_FILE " to load classes.", 0);
-		exit(1);
-	}
-
-	fscanf(fp, "%d\n", &maxClass);
-
-	alloc_mem(class_table, CLASS_DATA, maxClass + 1);
+	rw_table(type, SKILL_FILE, SKILL_DATA, maxSkill, "SKILL", sk,
+			 skillsavetable, skill_table);
 
-	if (!class_table)
-	{
-		bugf("Error! Class_table == NULL, MAX_CLASS : %d", maxClass);
-		exit(1);
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#CLASS"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		if (i >= maxClass)
-		{
-			bug("load_classes: number greater than maxClass", 0);
-			exit(1);
-		}
-
-		class_table[i] = clszero;
-		load_struct(fp, &cls, classsavetable, &class_table[i++]);
-	}
-
-	class_table[maxClass].name = NULL;
-
-	file_close(fp);
+	if (type == action_read)
+		skill_table[maxSkill].name = NULL;
 }
 
-void save_social_table(void)
+TABLESAVE(rw_races)
 {
-	FILE_DATA *fp;
-	SOCIAL_DATA *i;
-
-	fp = fopen_temp(SOCIAL_FILE);
-
-	if (!fp)
-	{
-		bug("save_socials: NULL fp", 0);
-		return;
-	}
-
-	for (i = social_first; i; i = i->next)
+	rw_list(type, RACE_FILE, RACE_DATA, race_first, race_last, next, prev,
+			new_race, "RACE", race, racesavetable);
+	if (type == action_read)
 	{
-		fprintf(fp->file, "#SOCIAL\n");
-		save_struct(fp->file, &soc, socialsavetable, i);
-		fprintf(fp->file, "#END\n\n");
+		default_race = new_race();
+		replace_string(default_race->name, "Unique");
 	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
 }
 
-void load_social_table(void)
+TABLESAVE(rw_groups)
 {
-	FILE *fp;
-	static SOCIAL_DATA socialzero;
-	SOCIAL_DATA *pSocial;
-	const char *word;
+	rw_table(type, GROUP_FILE, GROUP_DATA, maxGroup, "GROUP", grp,
+			 groupsavetable, group_table);
 
-	fp = file_open(SOCIAL_FILE, "r");
-
-	if (!fp)
-	{
-		bug("load_socials: Unable to open " SOCIAL_FILE " to load socials.", 0);
-		exit(1);
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#SOCIAL"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		pSocial = new_social();
-		*pSocial = socialzero;
-		load_struct(fp, &soc, socialsavetable, pSocial);
-		add_social(pSocial);
-	}
-
-	file_close(fp);
+	if (type == action_read)
+		group_table[maxGroup].name = NULL;
 }
 
-void save_clans(void)
+TABLESAVE(rw_classes)
 {
-	FILE_DATA *fp;
-	CLAN_DATA *i;
-
-	fp = fopen_temp(CLAN_FILE);
+	rw_table(type, CLASS_FILE, CLASS_DATA, maxClass, "CLASS", cls,
+			 classsavetable, class_table);
 
-	if (!fp)
-	{
-		bug("save_clans: NULL fp", 0);
-		return;
-	}
-
-	for (i = clan_first; i; i = i->next)
-	{
-		fprintf(fp->file, "#CLAN\n");
-		save_struct(fp->file, &clan, clansavetable, i);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
+	if (type == action_read)
+		class_table[maxClass].name = NULL;
 }
 
-void load_clans(void)
+TABLESAVE(rw_socials)
 {
-	FILE *fp;
-	static CLAN_DATA clanzero;
-	CLAN_DATA *i;
-	const char *word;
-
-	fp = file_open(CLAN_FILE, "r");
-
-	if (!fp)
-	{
-		bug("load_clans: Unable to open " CLAN_FILE " to load clans.", 0);
-		exit(1);
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#CLAN"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		i = new_clan();
-		*i = clanzero;
-		load_struct(fp, &clan, clansavetable, i);
-		LINK(i, clan_first, clan_last, next, prev);
-	}
-
-	file_close(fp);
+	rw_list(type, SOCIAL_FILE, SOCIAL_DATA, social_first, social_last, next,
+			prev, new_social, "SOCIAL", soc, socialsavetable);
 }
 
-void save_statlist(void)
+TABLESAVE(rw_gquest_data)
 {
-	STAT_DATA *pstat;
-	FILE_DATA *fp;
-
-	if ((fp = fopen_temp(STAT_FILE)) == NULL)
-	{
-		perror(STAT_FILE);
-		return;
-	}
-
-	for (pstat = stat_first; pstat != NULL; pstat = pstat->next)
-	{
-		fprintf(fp->file, "#STAT\n");
-		save_struct(fp->file, &stat, statsavetable, pstat);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
+	rw_single(type, GQUEST_FILE, "GQUESTDATA", gq, gqsavetable, gquest_info);
 }
 
-void load_statlist(void)
+TABLESAVE(rw_deities)
 {
-	FILE *fp;
-	STAT_DATA *pstat;
-	const char *word;
-
-	fp = file_open(STAT_FILE, "r");
-
-	if (!fp)
-		return;
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#STAT"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		pstat = new_stat_data();
-		load_struct(fp, &stat, statsavetable, pstat);
-		LINK(pstat, stat_first, stat_last, next, prev);
-	}
-	file_close(fp);
+	rw_list(type, DEITY_FILE, DEITY_DATA, deity_first, deity_last, next, prev,
+			new_deity, "DEITY", deity, deitysavetable);
 }
 
-void save_bans(void)
+TABLESAVE(rw_war_data)
 {
-	BAN_DATA *pban;
-	FILE_DATA *fp;
-
-	if ((fp = fopen_temp(BAN_FILE)) == NULL)
-	{
-		perror(BAN_FILE);
-		return;
-	}
-
-	for (pban = ban_first; pban != NULL; pban = pban->next)
-	{
-		fprintf(fp->file, "#BAN\n");
-		save_struct(fp->file, &ban, bansavetable, pban);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
+	rw_single(type, WAR_FILE, "WARDATA", war, warsavetable, war_info);
 }
 
-void load_bans(void)
+TABLESAVE(rw_channels)
 {
-	FILE *fp;
-	BAN_DATA *pban;
-	const char *word;
-
-	fp = file_open(BAN_FILE, "r");
-
-	if (!fp)
-		return;
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#BAN"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		pban = new_ban();
-		load_struct(fp, &ban, bansavetable, pban);
-		LINK(pban, ban_first, ban_last, next, prev);
-	}
-	file_close(fp);
+	rw_table(type, CHANNEL_FILE, CHANNEL_DATA, maxChannel, "CHANNEL",
+			 cd, chansavetable, channel_table);
 }
 
-bool save_gquest_data(void)
+void init_mud_data(void)
 {
-	FILE_DATA *fp;
-
-	if (!(fp = fopen_temp(GQUEST_FILE)))
-	{
-		bugf("Could not open file %s in order to save gquest data.",
-			 GQUEST_FILE);
-		return FALSE;
-	}
-
-	fprintf(fp->file, "#GQUESTDATA\n");
-	save_struct(fp->file, &gq, gqsavetable, &gquest_info);
-	fprintf(fp->file, "#END\n");
-	fprintf(fp->file, "\n#!\n");
-	fclose_temp(fp);
-	return TRUE;
-}
-
-bool load_gquest_data(void)
-{
-	FILE *fp;
-	const char *word;
-
-	end_gquest(NULL);
-
-	if (!(fp = file_open(GQUEST_FILE, "r")))
-	{
-		bugf("Could not open file %s in order to read gquest data. Creating.",
-			 GQUEST_FILE);
-		file_close(fp);
-		return save_gquest_data();
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#GQUESTDATA"))
-		{
-			bugf("Invalid gquest data file (%s).\n\r", GQUEST_FILE);
-			return FALSE;
-		}
-		load_struct(fp, &gq, gqsavetable, &gquest_info);
-	}
-
-	file_close(fp);
-	return TRUE;
-}
-
-void save_deities(void)
-{
-	FILE_DATA *fp;
-	DEITY_DATA *i;
-
-	fp = fopen_temp(DEITY_FILE);
-
-	if (!fp)
-	{
-		bug("save_deities: NULL fp", 0);
-		return;
-	}
-
-	for (i = deity_first; i; i = i->next)
-	{
-		fprintf(fp->file, "#DEITY\n");
-		save_struct(fp->file, &deity, deitysavetable, i);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
-}
-
-void load_deities(void)
-{
-	FILE *fp;
-	static DEITY_DATA deityzero;
-	DEITY_DATA *i;
-	const char *word;
-
-	fp = file_open(DEITY_FILE, "r");
-
-	if (!fp)
-	{
-		bug("load_deities: Unable to open " DEITY_FILE " to load deities.", 0);
-		save_deities();
-		return;
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#DEITY"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		i = new_deity();
-		*i = deityzero;
-		load_struct(fp, &deity, deitysavetable, i);
-		LINK(i, deity_first, deity_last, next, prev);
-	}
-
-	file_close(fp);
-}
-
-void save_webpasses(void)
-{
-	WPWD_DATA *ppwd;
-	FILE_DATA *fp;
-
-	if ((fp = fopen_temp(WPWD_FILE)) == NULL)
-	{
-		perror(WPWD_FILE);
-		return;
-	}
-
-	for (ppwd = wpwd_first; ppwd != NULL; ppwd = ppwd->next)
-	{
-		fprintf(fp->file, "#WPWD\n");
-		save_struct(fp->file, &pwd, pwdsavetable, ppwd);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
+	mud_info.pulsepersec = 4;
+	mud_info.mud_flags = 0;
+	mud_info.share_value = 100;
+	mud_info.arena = FIGHT_OPEN;
 }
 
-void load_webpasses(void)
+TABLESAVE(rw_mud_data)
 {
-	FILE *fp;
-	WPWD_DATA *ppwd;
-	const char *word;
-
-	fp = file_open(WPWD_FILE, "r");
-
-	if (!fp)
-	{
-		bug("Unable to open " WPWD_FILE " to load pwdlist.", 0);
-		save_webpasses();
-		file_close(fp);
-		return;
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#WPWD"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		ppwd = new_pwd();
-		load_struct(fp, &pwd, pwdsavetable, ppwd);
-		LINK(ppwd, wpwd_first, wpwd_last, next, prev);
-	}
-	file_close(fp);
-}
-
-void save_members(void)
-{
-	MBR_DATA *pmbr;
-	FILE_DATA *fp;
-
-	if ((fp = fopen_temp(MBR_FILE)) == NULL)
-	{
-		perror(MBR_FILE);
-		return;
-	}
-
-	for (pmbr = mbr_first; pmbr != NULL; pmbr = pmbr->next)
-	{
-		if (pmbr->clan == NULL)
-		{
-			bugf("%s member data invalid.", pmbr->name);
-			continue;
-		}
-		fprintf(fp->file, "#MBR\n");
-		save_struct(fp->file, &mbr, mbrsavetable, pmbr);
-		fprintf(fp->file, "#END\n\n");
-	}
-
-	fprintf(fp->file, "#!\n");
-
-	fclose_temp(fp);
-}
-
-void load_members(void)
-{
-	FILE *fp;
-	MBR_DATA *pmbr;
-	const char *word;
-
-	fp = file_open(MBR_FILE, "r");
-
-	if (!fp)
-	{
-		bug("Unable to open " MBR_FILE " to load members.", 0);
-		save_members();
-		return;
-	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#MBR"))
-		{
-			bugf("word doesn't exist (%s)", word);
-			exit(1);
-		}
-
-		pmbr = new_mbr();
-		load_struct(fp, &mbr, mbrsavetable, pmbr);
-		LINK(pmbr, mbr_first, mbr_last, next, prev);
-	}
-	file_close(fp);
+	if (type == action_read)
+		init_mud_data();
+	rw_single(type, MUD_FILE, "MUD", mud, mudsavetable, mud_info);
+	if (type == action_write)
+		write_time();
 }
 
-bool save_war_data(void)
+TABLESAVE(rw_music)
 {
-	FILE_DATA *fp;
 
-	if (!(fp = fopen_temp(WAR_FILE)))
+	rw_table(type, MUSIC_FILE, SONG_DATA, maxSongs, "SONG", song,
+			 songsavetable, song_table);
+	if (type == action_read)
 	{
-		bugf("Could not open file %s in order to save war data.", WAR_FILE);
-		return FALSE;
-	}
+		int i;
 
-	fprintf(fp->file, "#WARDATA\n");
-	save_struct(fp->file, &war, warsavetable, &war_info);
-	fprintf(fp->file, "#END\n");
-	fprintf(fp->file, "\n#!\n");
-	fclose_temp(fp);
-	return TRUE;
-}
-
-bool load_war_data(void)
-{
-	FILE *fp;
-	const char *word;
-
-	end_war();
-
-	if (!(fp = file_open(WAR_FILE, "r")))
-	{
-		bugf("Could not open file %s in order to read gquest data. Creating.",
-			 WAR_FILE);
-		file_close(fp);
-		return save_war_data();
+		song_table[maxSongs].name = NULL;
+		for (i = 0; i <= MAX_GLOBAL; i++)
+			channel_songs[i] = -1;
 	}
-
-	for (;;)
-	{
-		word = fread_word(fp);
-
-		if (!str_cmp(word, "#!"))
-			break;
-
-		if (str_cmp(word, "#WARDATA"))
-		{
-			bugf("Invalid war data file (%s).\n\r", WAR_FILE);
-			return FALSE;
-		}
-		load_struct(fp, &war, warsavetable, &war_info);
-	}
-
-	file_close(fp);
-	return TRUE;
 }
Only in new: tablesave.h
Only in new: tableset.c
Only in new: tablestat.c
diff -ur -x config -x o -x rom src/telnet.c new/telnet.c
--- src/telnet.c	Tue May 27 02:46:36 2003
+++ new/telnet.c	Sun Aug 31 19:23:21 2003
@@ -22,92 +22,119 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 #define TELOPTS
 #define TELCMDS
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
 #include "merc.h"
 #include "telnet.h"
 
-char echo_off_str[] = { IAC, WILL, TELOPT_ECHO, '\0' };
-char echo_on_str[] = { IAC, WONT, TELOPT_ECHO, '\0' };
-char echo_dont[] = { IAC, DONT, TELOPT_ECHO, '\0' };
-char echo_do[] = { IAC, DO, TELOPT_ECHO, '\0' };
-
-/* Telnet End-Of-Record */
-char eor_do[] = { IAC, DO, TELOPT_EOR, '\0' };
-char eor_will[] = { IAC, WILL, TELOPT_EOR, '\0' };
-char eor_dont[] = { IAC, DONT, TELOPT_EOR, '\0' };
-char eor_wont[] = { IAC, WONT, TELOPT_EOR, '\0' };
-
-/* Telnet window size */
-char naws_will[] = { IAC, WILL, TELOPT_NAWS, '\0' };
-char naws_dont[] = { IAC, DONT, TELOPT_NAWS, '\0' };
-char naws_do[] = { IAC, DO, TELOPT_NAWS, '\0' };
-char naws_wont[] = { IAC, WONT, TELOPT_NAWS, '\0' };
-char naws_sb[] = { IAC, SB, TELOPT_NAWS, '\0' };
-
-/* kill the socket after receiving either of those 2 strings */
-char iac_ip[] = { IAC, IP, '\0' };
-char iac_susp[] = { IAC, SUSP, '\0' };
-char iac_brk[] = { IAC, BREAK, '\0' };
+const char echo_off_str[] = { IAC, WILL, TELOPT_ECHO, NUL };
+const char echo_on_str[] = { IAC, WONT, TELOPT_ECHO, NUL };
+const char echo_dont[] = { IAC, DONT, TELOPT_ECHO, NUL };
+const char echo_do[] = { IAC, DO, TELOPT_ECHO, NUL };
+
+char eor_do[] = { IAC, DO, TELOPT_EOR, NUL };
+char eor_will[] = { IAC, WILL, TELOPT_EOR, NUL };
+char eor_dont[] = { IAC, DONT, TELOPT_EOR, NUL };
+char eor_wont[] = { IAC, WONT, TELOPT_EOR, NUL };
 
-/* telnet subnegotiation end */
-char iac_se[] = { IAC, SE, '\0' };
-
-/* go ahead after prompt string */
-const char go_ahead_str[] = { IAC, GA, '\0' };
+char iac_logout[] = { IAC, DO, TELOPT_LOGOUT, NUL };
 
 /* TTYSPEED .. used only to find out if the client is telopt capable */
-char tspd_will[] = { IAC, WILL, TELOPT_TSPEED, '\0' };
-char tspd_do[] = { IAC, DO, TELOPT_TSPEED, '\0' };
-char tspd_wont[] = { IAC, WONT, TELOPT_TSPEED, '\0' };
-char tspd_dont[] = { IAC, DONT, TELOPT_TSPEED, '\0' };
+char tspd_will[] = { IAC, WILL, TELOPT_TSPEED, NUL };
+char tspd_do[] = { IAC, DO, TELOPT_TSPEED, NUL };
+char tspd_wont[] = { IAC, WONT, TELOPT_TSPEED, NUL };
+char tspd_dont[] = { IAC, DONT, TELOPT_TSPEED, NUL };
+
+char naws_will[] = { IAC, WILL, TELOPT_NAWS, NUL };
+char naws_dont[] = { IAC, DONT, TELOPT_NAWS, NUL };
+char naws_do[] = { IAC, DO, TELOPT_NAWS, NUL };
+char naws_wont[] = { IAC, WONT, TELOPT_NAWS, NUL };
+char naws_sb[] = { IAC, SB, TELOPT_NAWS, NUL };
+
+char iac_ip[] = { IAC, IP, NUL };
+char iac_susp[] = { IAC, SUSP, NUL };
+char iac_brk[] = { IAC, BREAK, NUL };
+
+char iac_se[] = { IAC, SE, NUL };
+
+const char go_ahead_str[] = { IAC, GA, NUL };
+const char will_suppress_ga_str[] = { IAC, WILL, TELOPT_SGA, NUL };
+const char wont_suppress_ga_str[] = { IAC, WONT, TELOPT_SGA, NUL };
 
 #if !defined(NO_MCCP)
-/* mccp: compression negotiation strings */
-char compress_will[] = { IAC, WILL, TELOPT_COMPRESS, '\0' };
-char compress_do[] = { IAC, DO, TELOPT_COMPRESS, '\0' };
-char compress_dont[] = { IAC, DONT, TELOPT_COMPRESS, '\0' };
+char compress1_will[] = { IAC, WILL, TELOPT_COMPRESS, NUL };
+char compress1_do[] = { IAC, DO, TELOPT_COMPRESS, NUL };
+char compress1_dont[] = { IAC, DONT, TELOPT_COMPRESS, NUL };
+char compress1_wont[] = { IAC, WONT, TELOPT_COMPRESS, NUL };
+
+char compress2_will[] = { IAC, WILL, TELOPT_COMPRESS2, NUL };
+char compress2_do[] = { IAC, DO, TELOPT_COMPRESS2, NUL };
+char compress2_dont[] = { IAC, DONT, TELOPT_COMPRESS2, NUL };
+char compress2_wont[] = { IAC, WONT, TELOPT_COMPRESS2, NUL };
 #endif
 
+char msp_will[] = { IAC, WILL, TELOPT_MSP, NUL };
+char msp_do[] = { IAC, DO, TELOPT_MSP, NUL };
+char msp_dont[] = { IAC, DONT, TELOPT_MSP, NUL };
+char msp_wont[] = { IAC, WONT, TELOPT_MSP, NUL };
+
+char mxp_will[] = { IAC, WILL, TELOPT_MXP, NUL };
+char mxp_do[] = { IAC, DO, TELOPT_MXP, NUL };
+char mxp_dont[] = { IAC, DONT, TELOPT_MXP, NUL };
+char mxp_wont[] = { IAC, WONT, TELOPT_MXP, NUL };
+
+char s_mxp_supports[] = { "" MXPMODE(1) "<SUPPORTS" };
+char s_mxp_version[] = { "" MXPMODE(1) "<VERSION" };
+
+// Init string of Pueblo (pueblo.mozdev.org)
+// followed by the version
+char pueblo_str[] = { "PUEBLOCLIENT " };
+char ptype_3klient[] = { "3klient " };
+char imp_str[] = { "v1." };
+
+char ttype_do[] = { IAC, DO, TELOPT_TTYPE, NUL };
+char ttype_dont[] = { IAC, DONT, TELOPT_TTYPE, NUL };
+char ttype_sb[] = { IAC, SB, TELOPT_TTYPE, NUL };
+char ttype_send[] = { IAC, SB, TELOPT_TTYPE, SEND, IAC, SE, NUL };
+char ttype_will[] = { IAC, WILL, TELOPT_TTYPE, NUL };
+char ttype_wont[] = { IAC, WONT, TELOPT_TTYPE, NUL };
+
+char binary_do[] = { IAC, DO, TELOPT_BINARY, NUL };
+char binary_dont[] = { IAC, DONT, TELOPT_BINARY, NUL };
+char binary_will[] = { IAC, WILL, TELOPT_BINARY, NUL };
+char binary_wont[] = { IAC, WONT, TELOPT_BINARY, NUL };
+
+PROTOTYPE(void init_mxp, (DESCRIPTOR_DATA *));
+PROTOTYPE(void mxp_support, (DESCRIPTOR_DATA *, int, unsigned char *));
+PROTOTYPE(void mxp_version, (DESCRIPTOR_DATA *, int, unsigned char *));
+
 #define MTELOPT(string, command, len)					\
 	    if (!memcmp(&buf[i],(string),strlen((string))))		\
 	    { 								\
+		unsigned char *p = &buf[i];					\
+		telopt_debug(d,p,strlen((string))+(len)+telopt_lskip,FALSE);\
 		i += strlen((string)) - 1; 				\
 		(command); 						\
 		i += len;						\
+		i += telopt_lskip;					\
+		telopt_lskip = 0;					\
 		idx = i;						\
 		continue;						\
 	    }
 
-/* descriptor flags are used because some mud clients initiate the telnet
-   negotiation before the player logs on, this way as long there is a socket
-   open there is also flag strip that can indicate various results of the
-   negotiation.
- */
-void set_desc_flags(DESCRIPTOR_DATA * d)
-{
-	CHAR_DATA *ch = CH(d);
-
-	if (!ch)
-		return;
-
-	if (IS_SET(d->d_flags, DESC_TELOPT_EOR))
-		SET_BIT(ch->comm, COMM_TELNET_EOR);
-	else
-		REMOVE_BIT(ch->comm, COMM_TELNET_EOR);
-
-	if (IS_SET(ch->comm, COMM_NOCOLOUR))
-		REMOVE_BIT(d->d_flags, DESC_COLOUR);
-
-	return;
-}
+#define MSTRING(string, command, len)					\
+	    if (!memcmp(&buf[i],(string),strlen((string))))		\
+	    { 								\
+		(command); 						\
+		i += telopt_lskip;					\
+		telopt_lskip = 0;					\
+		idx = i;						\
+		continue;						\
+	    }
 
 /* init_telnet initiates the telnet negotiation with the mud client, although
    most of the mud clients support it, there is still few dinosaurs that don't
@@ -115,7 +142,7 @@
  */
 void init_telnet(DESCRIPTOR_DATA * d)
 {
-	write_to_descriptor(d, tspd_will, 0);
+	d_write(d, tspd_will, 0);
 
 	return;
 }
@@ -123,31 +150,124 @@
 void telopt_init(DESCRIPTOR_DATA * d)
 {
 
-	/* telnet end-of-record */
-	write_to_descriptor(d, eor_will, 0);
+	d_write(d, eor_will, 0);
+
+	d_write(d, naws_do, 0);
 
 #if !defined(NO_MCCP)
-	write_to_descriptor(d, compress_will, 0);
+	d_write(d, compress2_will, 0);
+
+	d_write(d, compress1_will, 0);
 #endif
 
-	/* telnet window size negotiation */
-	write_to_descriptor(d, naws_do, 0);
+	d_write(d, msp_will, 0);
+
+	d_write(d, mxp_will, 0);
+
+	/* terminal type */
+	d_write(d, ttype_do, 0);
+
+	d_write(d, binary_will, 0);
 
 	return;
 }
 
+void telopt_debug(DESCRIPTOR_DATA * d, unsigned char *string, int length,
+				  bool send)
+{
+	int i, j;
+	static char buf[MSL];		/* static so gdb hardware watchpoint works */
+	unsigned char c;
+	bool sb = FALSE;
+
+	if (!d)
+		return;
+
+	sprintf(buf, "Telopt: [%d][%s][ ", d->descriptor, (send) ? "send" : "recv");
+
+	if (string[0] != IAC)
+		return;
+
+	for (i = 0; i < length; i++)
+	{
+		c = string[i];
+
+		if (TELCMD_OK(c))
+		{
+			sprintf(buf + strlen(buf), "%s ", TELCMD(c));
+
+			if (c == SB)
+				sb = TRUE;
+			if (c == SE)
+				sb = FALSE;
+
+			continue;
+		}
+		else if (TELOPT_OK(c))
+		{
+			sprintf(buf + strlen(buf), "%s ", TELOPT(c));
+
+			if (sb && c == TELOPT_NAWS)
+			{
+				for (j = 0; j < 4; j++)
+				{
+					i++;
+					c = string[i];
+					sprintf(buf + strlen(buf), "%u ", c);
+				}
+			}
+
+			if (sb && c == TELOPT_TTYPE)
+			{
+				i++;
+				c = string[i];
+				if (c == SEND)
+				{
+					strcat(buf, "SEND ");
+				}
+				else if (c == IS)
+				{
+					strcat(buf, "IS ");
+					do
+					{
+						i++;
+						c = string[i];
+						sprintf(buf + strlen(buf), "%c", c);
+					}
+					while (c != IAC);
+					strcat(buf, " ");
+				}
+				else
+				{
+					sprintf(buf + strlen(buf), "%u ", c);
+				}
+			}
+
+			continue;
+		}
+		else
+		{
+			sprintf(buf + strlen(buf), "%u ", c);
+		}
+	}
+
+	sprintf(buf + strlen(buf), "]");
+	wiznet(buf, NULL, NULL, WIZ_TELNET, 0, MAX_LEVEL - 2);
+	return;
+}
+
 void telopt_ignore(void)
 {
 	return;
 }
 
-/* telopt_send is just a wrapper for write_to_descriptor, if you ever need to
+/* telopt_send is just a wrapper for d_write, if you ever need to
    send any string to the client that contains '\0' then you will have to modify
-   this so it reports the correct string lenght to the write_to_descriptor!
+   this so it reports the correct string length to the d_write!
  */
-void telopt_send(DESCRIPTOR_DATA * d, char *string)
+void telopt_send(DESCRIPTOR_DATA * d, char *string, int len)
 {
-	write_to_descriptor(d, string, strlen(string));
+	d_write(d, string, len);
 	return;
 }
 
@@ -174,50 +294,78 @@
 	return;
 }
 
-void telopt_echo(DESCRIPTOR_DATA * d, bool state)
+void telopt_msp(DESCRIPTOR_DATA * d, bool state)
 {
 	if (state)
-		SET_BIT(d->d_flags, DESC_TELOPT_ECHO);
+		SET_BIT(d->d_flags, DESC_MSP);
 	else
-		REMOVE_BIT(d->d_flags, DESC_TELOPT_ECHO);
+		REMOVE_BIT(d->d_flags, DESC_MSP);
+	return;
+}
+
+void telopt_mxp(DESCRIPTOR_DATA * d, bool state)
+{
+	if (state)
+	{
+		SET_BIT(d->d_flags, DESC_MXP);
+		init_mxp(d);
+	}
+	else
+	{
+		REMOVE_BIT(d->d_flags, DESC_MXP);
+	}
 	return;
 }
 
 #if !defined(NO_MCCP)
-void telopt_compress(DESCRIPTOR_DATA * d, bool state)
+void telopt_compress(DESCRIPTOR_DATA * d, bool state, int version)
 {
+	if (d->out_compress)
+		return;
+
 	if (state)
-		compressStart(d);
+		compressStart(d, version);
 	else
-		compressEnd(d);
+		compressEnd(d, version);
 	return;
 }
 #endif
 
+void telopt_echo(DESCRIPTOR_DATA * d, bool state)
+{
+	if (state)
+		SET_BIT(d->d_flags, DESC_TELOPT_ECHO);
+	else
+		REMOVE_BIT(d->d_flags, DESC_TELOPT_ECHO);
+	return;
+}
+
 /* telopt_unknown handles all the negotiation commands that the mud server
    doesn't understand
  */
-int telopt_unknown(DESCRIPTOR_DATA * d, unsigned char c, unsigned char t,
-				   bool quiet)
+int telopt_unknown(DESCRIPTOR_DATA * d, unsigned char c, char t, bool quiet)
 {
-	char buf[MAX_STRING_LENGTH];
-	char cmd[MAX_INPUT_LENGTH];
-	char opt[MAX_INPUT_LENGTH];
+	char buf[MSL];
+	char cmd[MIL];
+	char opt[MIL];
 	char rev;
 	char len = 1;
 
-	if (c == '\n' || c == '\r' || c == '\0')
+	if (c == '\n' || c == '\r' || c == NUL)
 		return 0;
 
 	if (TELCMD_OK(c))
 	{
 		sprintf(cmd, "%s", TELCMD(c));
 		if (c == IAC)
-			len = 1;			/* IAC IAC                      */
+			len = 1;
+
 		else if (c >= SB)
-			len = 2;			/* IAC DONT/DO/WONT/WILL/SB ??  */
+			len = 2;
+
 		else
-			len = 1;			/* IAC ??                       */
+			len = 1;
+
 	}
 
 	if (!quiet)
@@ -235,10 +383,14 @@
 			sprintf(opt, "COMPRESS-1");
 		else if (t == 86)
 			sprintf(opt, "COMPRESS-2");
+		else if (t == 90)
+			sprintf(opt, "MSP");
+		else if (t == 91)
+			sprintf(opt, "MXP");
 		else
 			sprintf(opt, "[%u]", t);
 
-		switch ((unsigned char) c)
+		switch (c)
 		{
 		case WILL:
 			rev = WONT;
@@ -257,7 +409,9 @@
 			break;
 		}
 		sprintf(buf, "%c%c%c", IAC, rev, t);
-		write_to_descriptor(d, buf, 0);
+		d_write(d, buf, 0);
+		sprintf(buf, "Unknown to client: IAC %s %s", cmd, opt);
+		log_string(buf);
 	}
 	return len;
 }
@@ -265,13 +419,10 @@
 /* this function is called when clients sends IAC WILL NAWS */
 void telopt_naws_do(DESCRIPTOR_DATA * d)
 {
-	return;
-
-	/* IAC WILL NAWS second time around */
-	if (IS_SET(d->d_flags, DESC_TELOPT_NAWS))
+	if (DESC_FLAGGED(d, DESC_TELOPT_NAWS))
 		return;
 
-	write_to_descriptor(d, naws_do, 0);
+	d_write(d, naws_do, 0);
 	return;
 }
 
@@ -279,18 +430,18 @@
    of data between IAC SB NAWS and IAC SE and converts them to the clients
    screen dimensions, then saves them in d->scr_width and d->scr_height
 */
-void telopt_naws(DESCRIPTOR_DATA * d, int i, char *inbuf)
+void telopt_naws(DESCRIPTOR_DATA * d, int i, unsigned char *inbuf)
 {
-	unsigned int x = 0, y = 0, t1, t2;
+	int x = 0, y = 0, t1, t2;
 
 	SET_BIT(d->d_flags, DESC_TELOPT_NAWS);
 
-	t1 = (unsigned char) inbuf[i + 1];
-	t2 = (unsigned char) inbuf[i + 2];
+	t1 = inbuf[i + 1];
+	t2 = inbuf[i + 2];
 	x = t2 + (t1 * 16);
 
-	t1 = (unsigned char) inbuf[i + 3];
-	t2 = (unsigned char) inbuf[i + 4];
+	t1 = inbuf[i + 3];
+	t2 = inbuf[i + 4];
 	y = t2 + (t1 * 16);
 
 	d->scr_width = URANGE(10, x, 250);
@@ -299,59 +450,189 @@
 	return;
 }
 
+void telopt_ttype(DESCRIPTOR_DATA * d, int i, int len, unsigned char *inbuf)
+{
+	int n;
+	int skip = 0;
+
+	d->ttype[0] = NUL;
+
+	SET_BIT(d->d_flags, DESC_TELOPT_TTYPE);
+
+	for (n = 0; n <= len; n++)
+	{
+		if (inbuf[n + i + 2] == IAC)
+		{
+			if (inbuf[n + i + 3] == SE)
+			{
+				telopt_lskip = skip;
+				return;
+			}
+		}
+		else
+		{
+			if (n < 59)
+			{
+				d->ttype[n] = inbuf[n + i + 2];
+				d->ttype[n + 1] = NUL;
+			}
+			skip++;
+		}
+	}
+
+	return;
+}
+
+void telopt_binary(DESCRIPTOR_DATA * d, bool state)
+{
+	if (state)
+		SET_BIT(d->d_flags, DESC_TELOPT_BINARY);
+	else
+		REMOVE_BIT(d->d_flags, DESC_TELOPT_BINARY);
+	return;
+}
+
+void pueblo_client(DESCRIPTOR_DATA * d, int i, unsigned char *inbuf)
+{
+	char *buf = (char *) &inbuf[i];
+	char send[MSL];
+
+	sscanf(buf, "PUEBLOCLIENT %lf", &d->pueblo_vers);
+
+	telopt_lskip = strlen(buf);
+
+	SET_BIT(d->d_flags, DESC_PUEBLO);
+	sprintf(send, "\n\rPueblo version %.2f detected...", d->pueblo_vers);
+	d_write(d, send, 0);
+
+	return;
+}
+
+void portal_3klient(DESCRIPTOR_DATA * d, int i, unsigned char *inbuf)
+{
+	char *buf = (char *) &inbuf[i];
+	static char tbuf[MSL];
+	int n;
+
+	SET_BIT(d->d_flags, DESC_TELOPT_TTYPE);
+	SET_BIT(d->d_flags, DESC_PORTAL);
+
+	sscanf(buf, "3klient %u~%s\r\n", &d->portal.keycode, tbuf);
+
+	for (n = 0; tbuf != NUL; n++)
+		if (isdigit(tbuf[n]))
+			break;
+
+	snprintf(d->portal.version, 20, "Portal %s", &tbuf[n]);
+
+	telopt_lskip = strlen(buf);
+
+	d_print(d, "\n\rPortal GT Detected...", 0);
+
+	return;
+
+}
+
+void fire_client(DESCRIPTOR_DATA * d, int i, unsigned char *inbuf)
+{
+	char *buf = (char *) &inbuf[i];
+	int vers;
+
+	SET_BIT(d->d_flags, DESC_IMP);
+
+	sscanf(buf, "v1.%2d", &vers);
+
+	telopt_lskip = strlen(buf);
+
+	d->imp_vers = (double) ((vers * .01) + 1);
+	d_printf(d, "\n\rFire Client version v%.2f detected...", d->imp_vers);
+
+	return;
+}
+
 /* process_telnet loops thru the buffer passed to it from read_from_descriptor
    and takes care of any IAC sequences found, at the same time it appends
    everything else to the end of d->inbuf
 */
-void process_telnet(DESCRIPTOR_DATA * d, int len, char *buf)
+void process_telnet(DESCRIPTOR_DATA * d, int len, unsigned char *buf)
 {
-	unsigned int i, idx;
+	int i, idx;
 	int iStart = strlen(d->inbuf);
 
 	if (len <= 0)
-		return;					/* nothing to process */
+		return;
 
-	for (i = 0; i <= (unsigned) len; i++)
+	for (i = 0; i <= len; i++)
 	{
-		if (buf[i] == (signed char) IAC)
+		if (buf[i] == IAC)
 		{
 			/* Telnet Window Size Negotiation */
 			MTELOPT(naws_sb, telopt_naws(d, i, buf), 6);
 			MTELOPT(naws_will, telopt_naws_do(d), 0);
 			MTELOPT(naws_wont, telopt_ignore(), 0);
 
+			MTELOPT(tspd_will, telopt_init(d), 0);
+			MTELOPT(tspd_do, telopt_init(d), 0);
+			MTELOPT(tspd_wont, telopt_init(d), 0);
+			MTELOPT(tspd_dont, telopt_init(d), 0);
+
 			/* Telnet End-Of-Record Negotiation */
 			MTELOPT(eor_will, telopt_eor(d, TRUE), 0);
 			MTELOPT(eor_do, telopt_eor(d, TRUE), 0);
 			MTELOPT(eor_wont, telopt_eor(d, FALSE), 0);
 			MTELOPT(eor_dont, telopt_eor(d, FALSE), 0);
 
-			MTELOPT(tspd_will, telopt_init(d), 0);
-			MTELOPT(tspd_do, telopt_init(d), 0);
-			MTELOPT(tspd_wont, telopt_init(d), 0);
-			MTELOPT(tspd_dont, telopt_init(d), 0);
+			/* Telnet Echo Negotiation */
+			MTELOPT(echo_dont, telopt_echo(d, FALSE), 0);
+			MTELOPT(echo_do, telopt_echo(d, TRUE), 0);
 
 #if !defined(NO_MCCP)
-			MTELOPT(compress_will, telopt_compress(d, TRUE), 0);
-			MTELOPT(compress_do, telopt_compress(d, TRUE), 0);
-			MTELOPT(compress_dont, telopt_compress(d, FALSE), 0);
+			MTELOPT(compress2_will, telopt_compress(d, TRUE, 2), 0);
+			MTELOPT(compress2_do, telopt_compress(d, TRUE, 2), 0);
+			MTELOPT(compress2_wont, telopt_compress(d, FALSE, 2), 0);
+			MTELOPT(compress2_dont, telopt_compress(d, FALSE, 2), 0);
+
+			MTELOPT(compress1_will, telopt_compress(d, TRUE, 1), 0);
+			MTELOPT(compress1_do, telopt_compress(d, TRUE, 1), 0);
+			MTELOPT(compress1_wont, telopt_compress(d, FALSE, 1), 0);
+			MTELOPT(compress1_dont, telopt_compress(d, FALSE, 1), 0);
 #endif
 
-			/* Telnet Echo Negotiation */
-			MTELOPT(echo_dont, telopt_echo(d, FALSE), 0);
-			MTELOPT(echo_do, telopt_echo(d, TRUE), 0);
+			MTELOPT(msp_will, telopt_msp(d, TRUE), 0);
+			MTELOPT(msp_do, telopt_msp(d, TRUE), 0);
+			MTELOPT(msp_wont, telopt_msp(d, FALSE), 0);
+			MTELOPT(msp_dont, telopt_msp(d, FALSE), 0);
+
+			MTELOPT(mxp_will, telopt_mxp(d, TRUE), 0);
+			MTELOPT(mxp_do, telopt_mxp(d, TRUE), 0);
+			MTELOPT(mxp_wont, telopt_mxp(d, FALSE), 0);
+			MTELOPT(mxp_dont, telopt_mxp(d, FALSE), 0);
+
+			/* Terminal Type */
+			MTELOPT(ttype_will, telopt_send(d, ttype_send, 6), 0);
+			MTELOPT(ttype_sb, telopt_ttype(d, i, len, buf), 1);
+			MTELOPT(ttype_do, telopt_ignore(), 0);
+			MTELOPT(ttype_wont, telopt_ignore(), 0);
+			MTELOPT(ttype_dont, telopt_ignore(), 0);
+
+			MTELOPT(binary_will, telopt_binary(d, TRUE), 1);
+			MTELOPT(binary_do, telopt_binary(d, TRUE), 1);
+			MTELOPT(binary_dont, telopt_binary(d, FALSE), 1);
+			MTELOPT(binary_wont, telopt_binary(d, FALSE), 1);
 
 			/* IP and SUSP - kill the descriptor */
 			MTELOPT(iac_ip, telopt_close(d), 0);
 			MTELOPT(iac_susp, telopt_close(d), 0);
 
+			MTELOPT(iac_logout, telopt_ignore(), 0);
+
 			/* BRK - ignore */
 			MTELOPT(iac_brk, telopt_ignore(), 0);
 
 			/* SE - end of sub negotiation */
 			MTELOPT(iac_se, telopt_ignore(), 0);
 
-			if (buf[i + 1] == (signed char) IAC)
+			if (buf[i + 1] == IAC)
 				continue;
 
 			/* No match for IAC sequence was found */
@@ -359,11 +640,51 @@
 		}
 		else
 		{
-			d->inbuf[iStart] = buf[i];
+			MSTRING(pueblo_str, pueblo_client(d, i, buf), 0);
+			MSTRING(ptype_3klient, portal_3klient(d, i, buf), 0);
+			MSTRING(imp_str, fire_client(d, i, buf), 0);
+			MSTRING(s_mxp_version, mxp_version(d, i, buf), 0);
+			MSTRING(s_mxp_supports, mxp_support(d, i + 4, buf), 0);
+
+			switch (buf[i])
+			{
+
+			case '~':			// turn any ~ into {- 
+				d->inbuf[iStart] = ANSI_KEY;
+				iStart++;
+				d->inbuf[iStart] = '-';
+				break;
+
+			default:
+				d->inbuf[iStart] = buf[i];
+				break;
+			}
+
 			iStart++;
 		}
 	}
+	return;
+}
+
+/* descriptor flags are used because some mud clients initiate the telnet
+   negotiation before the player logs on, this way as long there is a socket
+   open there is also flag strip that can indicate various results of the
+   negotiation.
+ */
+void set_desc_flags(DESCRIPTOR_DATA * d)
+{
+	CHAR_DATA *ch = CH(d);
+
+	if (!ch)
+		return;
+
+	if (IS_SET(d->d_flags, DESC_TELOPT_EOR))
+		SET_BIT(ch->comm, COMM_TELNET_EOR);
+	else
+		REMOVE_BIT(ch->comm, COMM_TELNET_EOR);
+
+	if (IS_SET(ch->comm, COMM_NOCOLOUR))
+		REMOVE_BIT(d->d_flags, DESC_COLOUR);
 
-	d->inbuf[iStart] = '\0';
 	return;
 }
diff -ur -x config -x o -x rom src/telnet.h new/telnet.h
--- src/telnet.h	Tue May 27 02:46:36 2003
+++ new/telnet.h	Sun Aug 31 19:23:21 2003
@@ -22,7 +22,7 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 /*
@@ -69,10 +69,81 @@
 #ifndef _TELNET_H_
 #define	_TELNET_H_
 
-void telopt_naws_do args((DESCRIPTOR_DATA * d));
-void process_telnet args((DESCRIPTOR_DATA * d, int len, char *buf));
-void set_desc_flags args((DESCRIPTOR_DATA * d));
-void init_telnet args((DESCRIPTOR_DATA * d));
+PROTOTYPE(void init_telnet, (DESCRIPTOR_DATA *));
+PROTOTYPE(void process_telnet, (DESCRIPTOR_DATA *, int, unsigned char *));
+PROTOTYPE(void set_desc_flags, (DESCRIPTOR_DATA *));
+
+EXTERN const char echo_off_str[];
+EXTERN const char echo_on_str[];
+EXTERN const char echo_dont[];
+EXTERN const char echo_do[];
+
+/* Telnet End-Of-Record */
+EXTERN char eor_do[];
+EXTERN char eor_will[];
+EXTERN char eor_dont[];
+EXTERN char eor_wont[];
+
+/* Telnet window size */
+EXTERN char naws_will[];
+EXTERN char naws_dont[];
+EXTERN char naws_do[];
+EXTERN char naws_wont[];
+EXTERN char naws_sb[];
+
+/* kill the socket after receiving either of those 2 strings */
+EXTERN char iac_ip[];
+EXTERN char iac_susp[];
+EXTERN char iac_brk[];
+
+/* telnet subnegotiation end */
+EXTERN char iac_se[];
+
+/* go ahead after prompt string */
+EXTERN const char go_ahead_str[];
+EXTERN const char will_suppress_ga_str[];
+EXTERN const char wont_suppress_ga_str[];
+
+#if !defined(NO_MCCP)
+/* mccp: compression negotiation strings */
+EXTERN char compress1_will[];
+EXTERN char compress1_do[];
+EXTERN char compress1_dont[];
+EXTERN char compress1_wont[];
+
+EXTERN char compress2_will[];
+EXTERN char compress2_do[];
+EXTERN char compress2_dont[];
+EXTERN char compress2_wont[];
+#endif
+
+EXTERN char tspd_will[];
+EXTERN char tspd_do[];
+EXTERN char tspd_wont[];
+EXTERN char tspd_dont[];
+
+EXTERN char msp_will[];
+EXTERN char msp_do[];
+EXTERN char msp_dont[];
+EXTERN char msp_wont[];
+
+EXTERN char mxp_will[];
+EXTERN char mxp_do[];
+EXTERN char mxp_dont[];
+EXTERN char mxp_wont[];
+EXTERN char start_mxp_str[];
+
+EXTERN char ttype_do[];
+EXTERN char ttype_dont[];
+EXTERN char ttype_sb[];
+EXTERN char ttype_send[];
+EXTERN char ttype_will[];
+EXTERN char ttype_wont[];
+
+EXTERN char binary_do[];
+EXTERN char binary_dont[];
+EXTERN char binary_will[];
+EXTERN char binary_wont[];
 
 /*
  * Definitions for the TELNET protocol.
@@ -100,13 +171,16 @@
 
 #define SYNCH	242				/* for telfunc calls */
 
+#define SEND	1				/* SEND for TTYPE negotiation */
+#define IS	0					/* SEND for TTYPE negotiation */
+
 #ifdef TELCMDS
 char *telcmds[] = { "EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK",
 	"BRK", "IP", "AO", "AYT", "EC", "EL", "GA", "SB", "WILL",
 	"WONT", "DO", "DONT", "IAC", 0
 };
 #else
-extern char *telcmds[];
+EXTERN char *telcmds[];
 #endif
 
 #define	TELCMD_FIRST	xEOF
@@ -168,6 +242,8 @@
 
 #define TELOPT_COMPRESS		 85	/* MCP (version 1)  */
 #define TELOPT_COMPRESS2	 86	/* MCP (version 2)  */
+#define    TELOPT_MSP       90
+#define    TELOPT_MXP       91
 
 #define TELOPT_PRAGMA_LOGON	138	/* Encrypted Logon option (PragmaSys) */
 #define TELOPT_SSPI_LOGON	139	/* MS SSPI Logon option (PragmaSys) */
@@ -176,7 +252,7 @@
 
 #define	TELOPT_EXOPL		255	/* extended-options-list */
 
-#define	NTELOPTS (1+TELOPT_SEND_URL)	/* ignore knowledge of non-seq opts */
+#define	NTELOPTS 141			/* ignore knowledge of non-seq opts */
 
 #ifdef TELOPTS
 char *telopts[NTELOPTS + 1] = {
@@ -268,7 +344,7 @@
 	SLC_NAMELIST
 };
 #else
-extern char *slc_names[];
+EXTERN char *slc_names[];
 #define	SLC_NAMES SLC_NAMELIST
 #endif
 
@@ -370,7 +446,7 @@
 	0
 };
 #else
-extern char *authtype_names[];
+EXTERN char *authtype_names[];
 #endif
 
 #define	AUTHTYPE_NAME_OK(x)	((unsigned int)(x) < AUTHTYPE_CNT)
@@ -413,8 +489,8 @@
 	"CAST128_CFB64", "CAST128_OFB64", 0,
 };
 #else
-extern char *encrypt_names[];
-extern char *enctype_names[];
+EXTERN char *encrypt_names[];
+EXTERN char *enctype_names[];
 #endif
 
 #define	ENCRYPT_NAME_OK(x)	((unsigned int)(x) < ENCRYPT_CNT)
@@ -422,41 +498,5 @@
 
 #define	ENCTYPE_NAME_OK(x)	((unsigned int)(x) < ENCTYPE_CNT)
 #define	ENCTYPE_NAME(x)		enctype_names[x]
-
-extern char echo_off_str[];
-extern char echo_on_str[];
-extern char echo_dont[];
-extern char echo_do[];
-
-/* Telnet End-Of-Record */
-extern char eor_do[];
-extern char eor_will[];
-extern char eor_dont[];
-extern char eor_wont[];
-
-/* Telnet window size */
-extern char naws_will[];
-extern char naws_dont[];
-extern char naws_do[];
-extern char naws_wont[];
-extern char naws_sb[];
-
-/* kill the socket after receiving either of those 2 strings */
-extern char iac_ip[];
-extern char iac_susp[];
-extern char iac_brk[];
-
-/* telnet subnegotiation end */
-extern char iac_se[];
-
-/* go ahead after prompt string */
-extern const char go_ahead_str[];
-
-#if !defined(NO_MCCP)
-/* mccp: compression negotiation strings */
-extern char compress_will[];
-extern char compress_do[];
-extern char compress_dont[];
-#endif
 
 #endif							/* !_TELNET_H_ */
Only in new: typedef.h
diff -ur -x config -x o -x rom src/update.c new/update.c
--- src/update.c	Tue May 27 02:46:36 2003
+++ new/update.c	Sun Aug 31 19:23:21 2003
@@ -22,31 +22,31 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
 
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
 #include "merc.h"
 #include "interp.h"
 #include "music.h"
 #include "webserver.h"
+#include "magic.h"
+#include "signals.h"
 
 /*
  * Local functions.
  */
-int hit_gain args((CHAR_DATA * ch));
-int mana_gain args((CHAR_DATA * ch));
-int move_gain args((CHAR_DATA * ch));
-void mobile_update args((void));
-void weather_update args((void));
-void char_update args((void));
-void obj_update args((void));
-void aggr_update args((void));
-void quest_update args((void));
+PROTOTYPE(int hit_gain, (CHAR_DATA *));
+PROTOTYPE(int mana_gain, (CHAR_DATA *));
+PROTOTYPE(int move_gain, (CHAR_DATA *));
+PROTOTYPE(void mobile_update, (void));
+PROTOTYPE(void weather_update, (void));
+PROTOTYPE(void time_update, (void));
+PROTOTYPE(void char_update, (void));
+PROTOTYPE(void obj_update, (void));
+PROTOTYPE(void aggr_update, (void));
+PROTOTYPE(void quest_update, (void));
+PROTOTYPE(void sendstat_update, (void));
 
 /* used for saving */
 
@@ -104,6 +104,28 @@
 				   "You gain %d hit point%s, %d mana, %d move, and %d practice%s.",
 				   add_hp, add_hp == 1 ? "" : "s", add_mana, add_move,
 				   add_prac, add_prac == 1 ? "" : "s");
+
+		if (!IS_NPC(ch) && ch->level < LEVEL_IMMORTAL)
+		{
+			int sn;
+
+			for (sn = 0; sn < maxSkill; sn++)
+			{
+				if (skill_level(ch, sn) == ch->level)
+				{
+					if (ch->pcdata->learned[sn] == 1)
+						chprintlnf(ch, "{MYou can now learn the {W%s {M%s.{x",
+								   skill_table[sn].name,
+								   skill_table[sn].spell_fun ==
+								   spell_null ? "skill" : "spell");
+					else
+						chprintlnf(ch, "{MYou can now use the {W%s {M%s.{x",
+								   skill_table[sn].name,
+								   skill_table[sn].spell_fun ==
+								   spell_null ? "skill" : "spell");
+				}
+			}
+		}
 	}
 	return;
 }
@@ -331,6 +353,8 @@
 		case POS_RESTING:
 			gain += get_curr_stat(ch, STAT_DEX) / 2;
 			break;
+		default:
+			break;
 		}
 
 		if (ch->pcdata->condition[COND_HUNGER] == 0)
@@ -510,143 +534,6 @@
 }
 
 /*
- * Update the weather.
- */
-void weather_update(void)
-{
-	char buf[MAX_STRING_LENGTH];
-	DESCRIPTOR_DATA *d;
-	int diff;
-
-	buf[0] = '\0';
-
-	switch (++time_info.hour)
-	{
-	case 5:
-		weather_info.sunlight = SUN_LIGHT;
-		strcat(buf, "The day has begun.\n\r");
-		break;
-
-	case 6:
-		weather_info.sunlight = SUN_RISE;
-		strcat(buf, "The sun rises in the east.\n\r");
-		break;
-
-	case 19:
-		weather_info.sunlight = SUN_SET;
-		strcat(buf, "The sun slowly disappears in the west.\n\r");
-		break;
-
-	case 20:
-		weather_info.sunlight = SUN_DARK;
-		strcat(buf, "The night has begun.\n\r");
-		break;
-
-	case 24:
-		time_info.hour = 0;
-		time_info.day++;
-		break;
-	}
-
-	if (time_info.day >= 35)
-	{
-		time_info.day = 0;
-		time_info.month++;
-	}
-
-	if (time_info.month >= 17)
-	{
-		time_info.month = 0;
-		time_info.year++;
-	}
-
-	/*
-	 * Weather change.
-	 */
-	if (time_info.month >= 9 && time_info.month <= 16)
-		diff = weather_info.mmhg > 985 ? -2 : 2;
-	else
-		diff = weather_info.mmhg > 1015 ? -2 : 2;
-
-	weather_info.change += diff * dice(1, 4) + dice(2, 6) - dice(2, 6);
-	weather_info.change = UMAX(weather_info.change, -12);
-	weather_info.change = UMIN(weather_info.change, 12);
-
-	weather_info.mmhg += weather_info.change;
-	weather_info.mmhg = UMAX(weather_info.mmhg, 960);
-	weather_info.mmhg = UMIN(weather_info.mmhg, 1040);
-
-	switch (weather_info.sky)
-	{
-	default:
-		bug("Weather_update: bad sky %d.", weather_info.sky);
-		weather_info.sky = SKY_CLOUDLESS;
-		break;
-
-	case SKY_CLOUDLESS:
-		if (weather_info.mmhg < 990 ||
-			(weather_info.mmhg < 1010 && number_bits(2) == 0))
-		{
-			strcat(buf, "The sky is getting cloudy.\n\r");
-			weather_info.sky = SKY_CLOUDY;
-		}
-		break;
-
-	case SKY_CLOUDY:
-		if (weather_info.mmhg < 970 ||
-			(weather_info.mmhg < 990 && number_bits(2) == 0))
-		{
-			strcat(buf, "It starts to rain.\n\r");
-			weather_info.sky = SKY_RAINING;
-		}
-
-		if (weather_info.mmhg > 1030 && number_bits(2) == 0)
-		{
-			strcat(buf, "The clouds disappear.\n\r");
-			weather_info.sky = SKY_CLOUDLESS;
-		}
-		break;
-
-	case SKY_RAINING:
-		if (weather_info.mmhg < 970 && number_bits(2) == 0)
-		{
-			strcat(buf, "Lightning flashes in the sky.\n\r");
-			weather_info.sky = SKY_LIGHTNING;
-		}
-
-		if (weather_info.mmhg > 1030 ||
-			(weather_info.mmhg > 1010 && number_bits(2) == 0))
-		{
-			strcat(buf, "The rain stopped.\n\r");
-			weather_info.sky = SKY_CLOUDY;
-		}
-		break;
-
-	case SKY_LIGHTNING:
-		if (weather_info.mmhg > 1010 ||
-			(weather_info.mmhg > 990 && number_bits(2) == 0))
-		{
-			strcat(buf, "The lightning has stopped.\n\r");
-			weather_info.sky = SKY_RAINING;
-			break;
-		}
-		break;
-	}
-
-	if (buf[0] != '\0')
-	{
-		for (d = descriptor_first; d != NULL; d = d->next)
-		{
-			if (d->connected == CON_PLAYING
-				&& IS_OUTSIDE(d->character) && IS_AWAKE(d->character))
-				chprint(d->character, buf);
-		}
-	}
-
-	return;
-}
-
-/*
  * Update all chars, including mobs.
 */
 void char_update(void)
@@ -868,9 +755,9 @@
 	 * Autosave and autoquit.
 	 * Check that these chars still exist.
 	 */
-	for (ch = char_first; ch != NULL; ch = ch_next)
+	for (ch = player_first; ch != NULL; ch = ch_next)
 	{
-		ch_next = ch->next;
+		ch_next = ch->next_player;
 
 		if (ch->desc != NULL && ch->desc->descriptor % 30 == save_number)
 		{
@@ -1144,9 +1031,7 @@
 
 void bank_update(void)
 {
-	FILE *fp;
 	int value = 0;
-	extern int share_value;
 
 	if ((time_info.hour < 6) || (time_info.hour > 18))
 		return;
@@ -1155,12 +1040,7 @@
 	value -= 100;
 	value /= 10;
 
-	share_value = URANGE(10, share_value + value, 1000);
-	if ((fp = file_open(BANK_FILE, "w")) != NULL)
-	{
-		fprintf(fp, "%d\n", share_value);
-	}
-	file_close(fp);
+	mud_info.share_value = URANGE(10, mud_info.share_value + value, 1000);
 }
 
 /*
@@ -1176,12 +1056,14 @@
 	static int pulse_violence;
 	static int pulse_point;
 	static int pulse_music;
+	static int pulse_sendstat;
+
+	crash_info.cmd_status = 4;
 
 	if (--pulse_area <= 0)
 	{
 		pulse_area = PULSE_AREA;
-		/* number_range( PULSE_AREA / 2, 3 * PULSE_AREA / 2 ); */
-		update_last_func(NULL, "pulse_area", "");
+		strcpy(crash_info.shrt_cmd, "pulse_area");
 		area_update();
 		bank_update();
 #if !defined(NO_WEB)
@@ -1193,31 +1075,31 @@
 	if (--pulse_music <= 0)
 	{
 		pulse_music = PULSE_MUSIC;
-		update_last_func(NULL, "pulse_music", "");
+		strcpy(crash_info.shrt_cmd, "pulse_music");
 		song_update();
 	}
 
 	if (--pulse_mobile <= 0)
 	{
 		pulse_mobile = PULSE_MOBILE;
-		update_last_func(NULL, "pulse_mobile", "");
+		strcpy(crash_info.shrt_cmd, "pulse_mobile");
 		mobile_update();
 	}
 
 	if (--pulse_violence <= 0)
 	{
 		pulse_violence = PULSE_VIOLENCE;
-		update_last_func(NULL, "pulse_violence", "");
+		strcpy(crash_info.shrt_cmd, "pulse_violence");
 		violence_update();
 	}
 
 	if (--pulse_point <= 0)
 	{
 		pulse_point = PULSE_TICK;
-/* number_range( PULSE_TICK / 2, 3 * PULSE_TICK / 2 ); */
-		update_last_func(NULL, "pulse_point", "");
+		strcpy(crash_info.shrt_cmd, "pulse_point");
 		wiznet("TICK!", NULL, NULL, WIZ_TICKS, 0, 0);
 		weather_update();
+		time_update();
 		char_update();
 		obj_update();
 		quest_update();
@@ -1225,11 +1107,20 @@
 		war_update();
 	}
 
-	update_last_func(NULL, "auction_update", "");
+	if (--pulse_sendstat <= 0)
+	{
+		pulse_sendstat = 1;
+		sendstat_update();		// update 1stmud statistics
+	}
+
+	strcpy(crash_info.shrt_cmd, "auction_update");
 	auction_update();
-	update_last_func(NULL, "aggr_update", "");
+	strcpy(crash_info.shrt_cmd, "crs_update");
+	crs_update();
+	strcpy(crash_info.shrt_cmd, "aggr_update");
 	aggr_update();
-	update_last_func(NULL, "N/A", "");
+	strcpy(crash_info.shrt_cmd, "N/A");
+	crash_info.cmd_status = 5;
 	tail_chain();
 	return;
 }
diff -ur -x config -x o -x rom src/war.c new/war.c
--- src/war.c	Tue May 27 02:46:36 2003
+++ new/war.c	Sun Aug 31 19:23:21 2003
@@ -22,15 +22,9 @@
 *       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              *
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
 *            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
 ***************************************************************************/
-#include <sys/types.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
 #include "merc.h"
 #include "tables.h"
 #include "recycle.h"
@@ -39,9 +33,6 @@
 #define WAR_KILLED	(BIT_A)
 #define WAR_DECOY	(BIT_B)
 
-void make_note(const char *board_name, const char *sender, const char *to,
-			   const char *subject, const int expire_days, const char *text);
-
 struct war_type
 {
 	const char *name;
@@ -86,29 +77,26 @@
 
 void new_warlist(CHAR_DATA * ch)
 {
-	WAR_LIST *wl;
+	WAR_DATA *wl;
 
 	if (!ch)
 		return;
 
-	alloc_mem(wl, WAR_LIST, 1);
+	alloc_mem(wl, WAR_DATA, 1);
 	wl->hit = ch->hit;
 	wl->mana = ch->mana;
 	wl->move = ch->move;
 	if (IS_NPC(ch))
 		wl->flags = WAR_DECOY;
 	else
-	{
 		wl->flags = 0;
-		war_info.inwar++;
-	}
 	wl->ch = ch;
 	ch->war = wl;
 	LINK(wl, war_info.first, war_info.last, next, prev);
 	return;
 }
 
-void free_warlist(WAR_LIST * wl)
+void free_warlist(WAR_DATA * wl)
 {
 	if (wl->ch)
 	{
@@ -157,7 +145,7 @@
 	argument = one_argument(argument, arg2);
 	argument = one_argument(argument, arg3);
 
-	if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0')
+	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || IS_NULLSTR(arg3))
 	{
 		int i;
 
@@ -215,24 +203,20 @@
 
 	if (!IS_IMMORTAL(ch))
 	{
-		char buf[MSL];
-
 		if (ch->pcdata->trivia < WAR_COST)
 		{
 
-			sprintf(buf,
-					"It costs %d Trivia Points to start a %s war.",
-					WAR_COST, wartype_name(type, FALSE));
-			do_mob_tell(ch, warmaster, buf);
+			mob_tell(ch, warmaster,
+					 "It costs %d Trivia Points to start a %s war.",
+					 WAR_COST, wartype_name(type, FALSE));
 			return FALSE;
 		}
 		else
 		{
 
-			sprintf(buf,
-					"Thank you %s, %s war started, you are %d trivia points lighter.",
-					ch->name, wartype_name(type, FALSE), WAR_COST);
-			do_mob_tell(ch, warmaster, buf);
+			mob_tell(ch, warmaster,
+					 "Thank you %s, %s war started, you are %d trivia points lighter.",
+					 ch->name, wartype_name(type, FALSE), WAR_COST);
 		}
 	}
 
@@ -255,7 +239,8 @@
 
 void auto_war(void)
 {
-	CHAR_DATA *wch, *wch_last, *warmaster;
+	CHAR_DATA *wch, *wch_last;
+	static CHAR_DATA *warmaster = NULL;
 	int maxlvl = 0, minlvl = MAX_LEVEL, middle = MAX_MORTAL_LEVEL / 2;
 	int clan = 0, count = 0, lbonus = 0, half = 0;
 	int heros = 0;
@@ -304,13 +289,17 @@
 		maxlvl = MAX_MORTAL_LEVEL;
 	else
 		maxlvl = UMIN(MAX_MORTAL_LEVEL, number_range((middle * 3) / 2, maxlvl));
-	for (warmaster = char_first; warmaster != NULL; warmaster = warmaster->next)
-		if (warmaster->pIndexData
-			&& warmaster->pIndexData->vnum == MOB_VNUM_WARMASTER)
-			break;
+	if (warmaster == NULL)
+	{
+		for (warmaster = char_first; warmaster != NULL;
+			 warmaster = warmaster->next)
+			if (warmaster->pIndexData
+				&& warmaster->pIndexData->vnum == MOB_VNUM_WARMASTER)
+				break;
+	}
 	war_info.status = WAR_WAITING;
 	replace_string(war_info.who,
-				   (!warmaster ? "AutoWar (tm)" : warmaster->short_descr));
+				   (!warmaster ? "AutoWar" : warmaster->short_descr));
 	war_info.min_level = minlvl;
 	war_info.max_level = maxlvl;
 
@@ -339,25 +328,28 @@
 
 void end_war(void)
 {
-	WAR_LIST *wl, *wl_next;
+	WAR_DATA *wl, *wl_next;
 
 	for (wl = war_info.first; wl != NULL; wl = wl_next)
 	{
 		wl_next = wl->next;
 
-		if (!IS_SET(wl->flags, WAR_DECOY) && wl->ch)
+		if (wl->ch)
 		{
 			stop_fighting(wl->ch, TRUE);
-			if (!IS_SET(wl->flags, WAR_KILLED))
+			if (!IS_SET(wl->flags, WAR_DECOY))
 			{
-				char_from_room(wl->ch);
-				char_to_room(wl->ch, get_room_index(ROOM_VNUM_TEMPLE));
+				if (!IS_SET(wl->flags, WAR_KILLED))
+				{
+					char_from_room(wl->ch);
+					char_to_room(wl->ch, get_room_index(ROOM_VNUM_TEMPLE));
+				}
+				wl->ch->hit = wl->hit;
+				wl->ch->mana = wl->mana;
+				wl->ch->move = wl->move;
+				update_pos(wl->ch);
+				do_function(wl->ch, &do_look, "auto");
 			}
-			wl->ch->hit = wl->hit;
-			wl->ch->mana = wl->mana;
-			wl->ch->move = wl->move;
-			update_pos(wl->ch);
-			do_function(wl->ch, &do_look, "auto");
 		}
 		free_warlist(wl);
 	}
@@ -436,7 +428,7 @@
 
 	argument = one_argument(argument, arg);
 
-	if (arg[0] == '\0')
+	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "{gSyntax:{R  war {Wstart <minlev> <maxlev> <#type>");
 		chprintln(ch, "         {Rwar {Wtalk <message>");
@@ -521,7 +513,7 @@
 	}
 	else if (!str_cmp(arg, "status"))
 	{
-		WAR_LIST *wl;
+		WAR_DATA *wl;
 		bool found = FALSE;
 
 		chprintlnf(ch, "{g%s{x",
@@ -550,7 +542,7 @@
 	}
 	else if (!str_cmp(arg, "decoy"))
 	{
-		WAR_LIST *wl;
+		WAR_DATA *wl;
 		CHAR_DATA *dc;
 		char buf[MSL];
 		int count = 0;
@@ -669,6 +661,7 @@
 			char_from_room(ch);
 			char_to_room(ch, location);
 			new_warlist(ch);
+			war_info.inwar++;
 			announce(NULL, INFO_WAR, "%s joins the war!", warrior_status(ch));
 			act("$n arrives to get $s ass whipped!", ch, NULL, NULL, TO_ROOM);
 			do_function(ch, &do_look, "auto");
@@ -681,7 +674,7 @@
 
 bool abort_war(void)
 {
-	WAR_LIST *cwl, *vwl;
+	WAR_DATA *cwl, *vwl;
 
 	for (cwl = war_info.first; cwl != NULL; cwl = cwl->next)
 	{
@@ -703,49 +696,42 @@
 void note_war(CHAR_DATA * ch)
 {
 	BUFFER *output;
-	char sender[MIL], subject[MIL], buf[MSL];
-	WAR_LIST *wl;
+	char sender[MIL], subject[MIL];
+	WAR_DATA *wl;
 
 	if (war_info.status != WAR_RUNNING)
 		return;
 
 	output = new_buf();
-	add_buf(output, "{WWAR INFO{g\n\r--------{x\n\r");
-	sprintf(buf, "{RStarted by  : {W%s\n\r",
-			IS_NULLSTR(war_info.who) ? "AutoWar (Tm)" : war_info.who);
-	add_buf(output, buf);
-	sprintf(buf, "{RLevels      : {W%d - %d{x\n\r", war_info.min_level,
-			war_info.max_level);
-	add_buf(output, buf);
-	sprintf(buf, "{RType        : {W%s war.{x\n\r",
-			wartype_name(war_info.wartype, FALSE));
-	add_buf(output, buf);
-	add_buf(output, "{WWAR COMBATENTS{g\n\r--------------{x\n\r");
+	bprintln(output, "{WWAR INFO{g\n\r--------{x");
+	bprintlnf(output, "{RStarted by  : {W%s",
+			  IS_NULLSTR(war_info.who) ? "AutoWar" : war_info.who);
+	bprintlnf(output, "{RLevels      : {W%d - %d{x", war_info.min_level,
+			  war_info.max_level);
+	bprintlnf(output, "{RType        : {W%s war.{x",
+			  wartype_name(war_info.wartype, FALSE));
+	bprintln(output, "{WWAR COMBATENTS{g\n\r--------------{x");
 	for (wl = war_info.first; wl != NULL; wl = wl->next)
 	{
 		if (IS_SET(wl->flags, WAR_DECOY) || !wl->ch)
 			continue;
 
-		sprintf(buf, "{W%s{x\n\r", warrior_status(wl->ch));
-		add_buf(output, buf);
+		bprintlnf(output, "{W%s{x\n\r", warrior_status(wl->ch));
 	}
-	add_buf(output, "{g--------------{x\n\r");
+	bprintln(output, "{g--------------{x");
 	switch (war_info.wartype)
 	{
 	case WAR_RACE:
 	case WAR_CLASS:
-		sprintf(buf, "{WThe {R%s's{W won this war.{x\n\r", wartype_info(ch));
-		add_buf(output, buf);
+		bprintlnf(output, "{WThe {R%s's{W won this war.{x", wartype_info(ch));
 		break;
 	default:
-		sprintf(buf, "{R%s{W won this war.{x\n\r", wartype_info(ch));
-		add_buf(output, buf);
+		bprintlnf(output, "{R%s{W won this war.{x", wartype_info(ch));
 		break;
 	}
 
 	sprintf(subject, "War Info %s\n\r", str_time(current_time, -1, NULL));
-	sprintf(sender, "%s",
-			IS_NULLSTR(war_info.who) ? "AutoWar (Tm)" : war_info.who);
+	sprintf(sender, "%s", IS_NULLSTR(war_info.who) ? "AutoWar" : war_info.who);
 	make_note("General", sender, "All", subject, 15, buf_string(output));
 	free_buf(output);
 	return;
@@ -788,7 +774,7 @@
 			}
 			else
 			{
-				WAR_LIST *wl;
+				WAR_DATA *wl;
 
 				announce(NULL, INFO_WAR,
 						 "The battle begins! %d players are fighting!",
@@ -842,7 +828,7 @@
 
 void check_war(CHAR_DATA * ch, CHAR_DATA * victim)
 {
-	WAR_LIST *wl, *wl_next;
+	WAR_DATA *wl, *wl_next;
 
 	if (war_info.status == WAR_OFF)
 		return;
@@ -938,7 +924,7 @@
 {
 	DESCRIPTOR_DATA *d;
 
-	if (argument[0] == '\0')
+	if (IS_NULLSTR(argument))
 	{
 		chprintln(ch,
 				  "Wartalk about what?\n\rUse 'info war' to toggle this channel.");
@@ -953,7 +939,8 @@
 
 		if (d->connected == CON_PLAYING && (victim = CH(d)) != ch
 			&& !IS_SET(victim->info_settings, INFO_WAR)
-			&& !IS_SET(victim->comm, COMM_QUIET))
+			&& !IS_SET(victim->comm, COMM_QUIET)
+			&& !is_ignoring(ch, victim->name, IGNORE_CHANNELS))
 		{
 			chprintf(victim, "{Y({RWarTalk{Y) {g%s drums: %s{x",
 					 PERS(ch, victim), argument);
Only in new: weather.c
diff -ur -x config -x o -x rom src/webserver.c new/webserver.c
--- src/webserver.c	Tue May 27 02:46:36 2003
+++ new/webserver.c	Sun Aug 31 19:23:21 2003
@@ -58,24 +58,6 @@
 
 /* Modded for use on 1stMUD by Markanth 14/05/2003 */
 
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#if !defined(WIN32)
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#endif
-#include <fcntl.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
 #include "merc.h"
 #include "webserver.h"
 #include "globals.h"
@@ -87,6 +69,21 @@
 #include "magic.h"
 #include "gsn.h"
 #include "telnet.h"
+#include "tablesave.h"
+
+WPWD_DATA pwd;
+
+const struct savetable_type pwdsavetable[] = {
+	{"name", FIELD_STRING, (void *) &pwd.name, NULL, NULL},
+	{"pwd", FIELD_STRING, (void *) &pwd.passw, NULL, NULL},
+	{NULL, 0, NULL, NULL, NULL}
+};
+
+TABLESAVE(rw_webpasswds)
+{
+	rw_list(type, WPWD_FILE, WPWD_DATA, wpwd_first, wpwd_last, next, prev,
+			new_pwd, "WPWD", pwd, pwdsavetable);
+}
 
 void update_webpasses(CHAR_DATA * ch, bool pDelete)
 {
@@ -104,7 +101,7 @@
 		{
 			UNLINK(curr, wpwd_first, wpwd_last, next, prev);
 			free_pwd(curr);
-			save_webpasses();
+			rw_webpasswds(action_write);
 		}
 	}
 	if (pDelete || IS_NULLSTR(ch->pcdata->webpass))
@@ -114,7 +111,7 @@
 	replace_string(curr->name, ch->name);
 	replace_string(curr->passw, ch->pcdata->webpass);
 	LINK(curr, wpwd_first, wpwd_last, next, prev);
-	save_webpasses();
+	rw_webpasswds(action_write);
 	return;
 }
 
@@ -160,12 +157,12 @@
 		return;
 	}
 
-	write_to_descriptor(ch->desc, echo_off_str, 0);
+	d_write(ch->desc, echo_off_str, 0);
 
 	if (strlen(arg1) < 5)
 	{
 		chprintln(ch, "New password must be at least five characters long.");
-		write_to_descriptor(ch->desc, echo_on_str, 0);
+		d_write(ch->desc, echo_on_str, 0);
 		return;
 	}
 
@@ -175,7 +172,7 @@
 		if (*p == '~')
 		{
 			chprintln(ch, "New password not acceptable, try again.");
-			write_to_descriptor(ch->desc, echo_on_str, 0);
+			d_write(ch->desc, echo_on_str, 0);
 			return;
 		}
 	}
@@ -184,7 +181,7 @@
 	save_char_obj(ch);
 	update_webpasses(ch, FALSE);
 	chprintln(ch, "Ok.");
-	write_to_descriptor(ch->desc, echo_on_str, 0);
+	d_write(ch->desc, echo_on_str, 0);
 	return;
 }
 
@@ -230,8 +227,6 @@
 	64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
 };
 
-bool WebUP = FALSE;
-
 /*
  * Decode a base64 encoded string
  */
@@ -306,14 +301,14 @@
 	if ((web_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
 	{
 		log_string("----> Web Server: Error getting socket");
-		perror("web-socket");
+		log_error("web-socket");
 		return FALSE;
 	}
 
 	if (setsockopt(web_socket, SOL_SOCKET, SO_REUSEADDR, (void *) &x, sizeof(x))
 		< 0)
 	{
-		perror("init_web: SO_REUSEADDR");
+		log_error("init_web: SO_REUSEADDR");
 		close(web_socket);
 		web_socket = -1;
 		return FALSE;
@@ -329,7 +324,7 @@
 		if (setsockopt
 			(web_socket, SOL_SOCKET, SO_LINGER, (void *) &ld, sizeof(ld)) < 0)
 		{
-			perror("Init_web: SO_LINGER");
+			log_error("Init_web: SO_LINGER");
 			close(web_socket);
 			web_socket = -1;
 			return FALSE;
@@ -344,7 +339,7 @@
 	if ((bind(web_socket, (struct sockaddr *) &my_addr, sizeof(my_addr))) == -1)
 	{
 		log_string("----> Web Server: Error binding socket");
-		perror("web-bind");
+		log_error("web-bind");
 		close(web_socket);
 		web_socket = -1;
 		return FALSE;
@@ -354,7 +349,7 @@
 	/* We might now since I've attached this to the live web page - Samson */
 	if (listen(web_socket, 20) < 0)
 	{
-		perror("web-listen");
+		log_error("web-listen");
 		close(web_socket);
 		web_socket = -1;
 		return FALSE;
@@ -390,17 +385,18 @@
 	if (FD_ISSET(web_socket, &readfds))
 	{
 		/* NEW CONNECTION -- INIT & ADD TO LIST */
+		size_t size;
 
 		alloc_mem(current, WEB_DESCRIPTOR, 1);
-		current->sin_size = sizeof(struct sockaddr_in);
+		size = sizeof(struct sockaddr_in);
 		current->request[0] = '\0';
 
 		if ((current->fd =
 			 accept(web_socket, (struct sockaddr *) &(current->their_addr),
-					&(current->sin_size))) == -1)
+					(socklen_t *) & (size))) == -1)
 		{
 			log_string("----> Web Server: Error accepting connection");
-			perror("web-accept");
+			log_error("web-accept");
 			free_mem(current);
 			FD_CLR(web_socket, &readfds);
 			return;
@@ -420,7 +416,7 @@
 
 			if ((numbytes = read(current->fd, buf, sizeof(buf))) == -1)
 			{
-				perror("web-read");
+				log_error("web-read");
 				continue;
 			}
 
@@ -461,6 +457,9 @@
 	va_list args;
 	int len;
 
+	if (IS_NULLSTR(fmt))
+		return 0;
+
 	va_start(args, fmt);
 
 	len = vsnprintf(buf, sizeof(buf), fmt, args);
@@ -628,6 +627,67 @@
 	return (strlen(out));
 }
 
+const char *ansitohtml(int attr, int fore)
+{
+	bool b = (attr == CL_BRIGHT);
+	int random_fore(void);
+
+	switch (fore)
+	{
+	case FG_BLACK:
+		return b ? "gray" : "black";
+	case FG_RED:
+		return b ? "red" : "maroon";
+	case FG_GREEN:
+		return b ? "lime" : "green";
+	case FG_YELLOW:
+		return b ? "yellow" : "olive";
+	case FG_BLUE:
+		return b ? "blue" : "navy";
+	case FG_MAGENTA:
+		return b ? "magenta" : "purple";
+	case FG_CYAN:
+		return b ? "cyan" : "teal";
+	case FG_WHITE:
+		return b ? "white" : "silver";
+	case FG_RANDOM:
+		return ansitohtml(attr, random_fore());
+	case FG_NONE:
+	default:
+		return
+			"<script type='text/javascript'>document.writeln(document.fgColor);</script>";
+	}
+}
+
+int html_custom_colour(int slot, char *string)
+{
+	char code[MIL];
+	char out[MSL];
+	char *p = NUL;
+
+	if (lastcolor == TRUE)
+	{
+		strcpy(out, "</FONT>");
+		lastcolor = FALSE;
+	}
+	else
+		out[0] = NUL;
+
+	sprintf(code, "<FONT color=\"%s\">",
+			ansitohtml(cslot_table[slot].col_attr, cslot_table[slot].col_fore));
+	lastcolor = TRUE;
+	strcat(out, code);
+
+	p = out;
+	while (*p != NUL)
+	{
+		*string = *p++;
+		*++string = NUL;
+	}
+
+	return (strlen(out));
+}
+
 void html_colourconv(char *buffer, const char *txt)
 {
 	const char *point;
@@ -651,9 +711,25 @@
 		}
 		else if (*point == ANSI_CUSTOM)
 		{
+			int slot = 0;
+
 			point++;
-			while (*point != ANSI_END)
+			while (*point && *point != ANSI_END)
+			{
+				if (isdigit(*point))
+					slot = (slot * 10) + (*point - '0');
 				point++;
+			}
+			if (slot < 0 || slot >= MAX_CUSTOM_COLOUR)
+			{
+				bug("invalid custom color");
+			}
+			else
+			{
+				skip = html_custom_colour(slot, buffer);
+				while (skip-- > 0)
+					++buffer;
+			}
 			continue;
 		}
 		if (*point == '<')
@@ -719,9 +795,27 @@
 	return;
 }
 
-const char *HTTP_URL(void)
+const char *HTTP_URL(const char *fmt, ...)
 {
-	return FORMATF(DEFAULT_URL, HOSTNAME, WEBSERVERPORT);
+	static char buf[5][MIL];
+	char path[MIL];
+	char *result;
+	static int i;
+
+	path[0] = NUL;
+	if (!IS_NULLSTR(fmt))
+	{
+		va_list args;
+		va_start(args, fmt);
+		vsnprintf(path, sizeof(path), fmt, args);
+		va_end(args);
+	}
+
+	++i;
+	i %= 5;
+	result = buf[i];
+	sprintf(result, DEFAULT_URL "%s", HOSTNAME, WEBSERVERPORT, path);
+	return result;
 }
 
 char *get_next(char *path)
@@ -737,13 +831,10 @@
 
 	buf[i] = strchr(path, '/');
 
-	if (IS_NULLSTR(buf[i]))
-		return buf[i];
-	else
-	{
+	if (!IS_NULLSTR(buf[i]))
 		buf[i]++;
-		return buf[i];
-	}
+
+	return buf[i];
 }
 
 bool get_name_password(WEB_DESCRIPTOR * wdesc, const char *stuff)
@@ -823,12 +914,11 @@
 {
 	int i;
 
-	send_buf(wdesc->fd, DOCTYPE);
 	send_buf(wdesc->fd, "<HTML>\n");
 	send_buf(wdesc->fd, "<HEAD>\n");
 	send_buf(wdesc->fd, "<TITLE>%s @ %s</TITLE>\n", title, MUD_NAME);
 	send_buf(wdesc->fd,
-			 "</HEAD><BODY BGCOLOR=BLACK TEXT=WHITE LINK=#FFFFCC VLINK=#FFFFCC>\n");
+			 "</HEAD><BODY BGCOLOR=BLACK TEXT=WHITE LINK=YELLOW VLINK=RED>\n");
 	send_buf(wdesc->fd,
 			 "<TABLE CELLSPACING=3 CELLPADDING=3 BORDER=0><TR><TD VALIGN=TOP WIDTH=15%%>\n");
 	send_buf(wdesc->fd, "<UL>\n");
@@ -837,8 +927,8 @@
 		if (request_table[i].name == NULL)
 			continue;
 
-		send_buf(wdesc->fd, "<LI><A href=\"%s%s\">%s</A></LI>\n", HTTP_URL(),
-				 request_table[i].req, request_table[i].name);
+		send_buf(wdesc->fd, "<LI><A href=\"%s\">%s</A></LI>\n",
+				 HTTP_URL(request_table[i].req), request_table[i].name);
 	}
 	send_buf(wdesc->fd, "</UL>\n");
 	send_buf(wdesc->fd, "</TD><TD VALIGN=TOP WIDTH=100%%>\n");
@@ -858,33 +948,16 @@
 
 void print_file(WEB_DESCRIPTOR * wdesc, char *filename)
 {
-	FILE *fp;
-	char buf[MSL * 4];
-	int c;
-	int num = 0;
-
-	if ((fp = file_open(filename, "r")) != NULL)
-	{
-		while (!feof(fp))
-		{
-			while ((buf[num] = fgetc(fp)) != EOF && buf[num] != '\n'
-				   && buf[num] != '\r' && num < (MSL * 4 - 2))
-				num++;
-			c = fgetc(fp);
-			if ((c != '\n' && c != '\r') || c == buf[num])
-				ungetc(c, fp);
-			buf[num++] = '\n';
-			buf[num] = '\0';
-			send_buf(wdesc->fd, buf);
-			num = 0;
-		}
+	READ_DATA *fp;
 
-		file_close(fp);
+	if ((fp = open_read(filename)) != NULL)
+	{
+		send_buf(wdesc->fd, fp->str);
+		close_read(fp);
 	}
 	else
 	{
 		logf("Failed to open file %s.", filename);
-		file_close(fp);
 	}
 }
 
@@ -948,8 +1021,8 @@
 		char temp[MSL];
 
 		html_colourconv(buf, obj->description);
-		sprintf(temp, "<A href=\"%sobjs/%ld\">%s</A><br>",
-				HTTP_URL(), obj->pIndexData->vnum, buf);
+		sprintf(temp, "<A href=\"%s\">%s</A><br>",
+				HTTP_URL("objs/%ld", obj->pIndexData->vnum), buf);
 		strcat(output, temp);
 	}
 
@@ -1079,7 +1152,7 @@
 			strcat(buf, "(THIEF) ");
 		if (IS_SET(victim->comm, COMM_QUIET))
 			strcat(buf, "[QUIET] ");
-		if (victim->desc && victim->desc->editor != 0)
+		if (victim->desc && victim->desc->editor != ED_NONE)
 			strcat(buf, "[OLC] ");
 		if (victim->pcdata->in_progress != NULL)
 			strcat(buf, "[Note] ");
@@ -1109,8 +1182,9 @@
 		if (IS_NPC(victim))
 		{
 			html_colourconv(cbuf, victim->long_descr);
-			sprintf(temp, "<A href=\"%schars/%ld\">%s</A>", HTTP_URL(),
-					victim->pIndexData->vnum, cbuf);
+			sprintf(temp, "<A href=\"%s\">%s</A>", HTTP_URL("chars/%ld",
+															victim->pIndexData->
+															vnum), cbuf);
 			strcat(buf, temp);
 		}
 		return (buf);
@@ -1118,8 +1192,9 @@
 	if (IS_NPC(victim))
 	{
 		html_colourconv(cbuf, victim->short_descr);
-		sprintf(temp, "<A href=\"%schars/%ld\">%s</A>", HTTP_URL(),
-				victim->pIndexData->vnum, cbuf);
+		sprintf(temp, "<A href=\"%s\">%s</A>", HTTP_URL("chars/%ld",
+														victim->pIndexData->
+														vnum), cbuf);
 		strcat(buf, temp);
 	}
 	else
@@ -1242,6 +1317,8 @@
 		else
 			strcat(buf, "someone who left??");
 		break;
+	default:
+		break;
 	}
 	return (buf);
 }
@@ -1319,7 +1396,11 @@
 	print_header(wdesc, "Rules");
 	send_buf(wdesc->fd, "<PRE>\n");
 	if ((pHelp = help_lookup("RULES")) != NULL)
-		send_buf(wdesc->fd, fix_string(smash_colour(pHelp->text)));
+	{
+		char buf[MSL * 2];
+		html_colourconv(buf, pHelp->text);
+		send_buf(wdesc->fd, buf);
+	}
 	else
 		send_buf(wdesc->fd, "There are no rules!! Anarchy!!\n");
 	send_buf(wdesc->fd, "</PRE>\n");
@@ -1506,8 +1587,8 @@
 	send_buf(wdesc->fd, "</TABLE>\n");
 
 	send_buf(wdesc->fd,
-			 "<P>To view skills in class specific tables, visit the <a href=\"%sclass\">Classes</a> section.</P>\n",
-			 HTTP_URL());
+			 "<P>To view skills in class specific tables, visit the <a href=\"%s\">Classes</a> section.</P>\n",
+			 HTTP_URL("class"));
 
 	send_buf(wdesc->fd, "<H3><A NAME=\"RaceSkills\">Race Skills</A></H3>\n");
 	send_buf(wdesc->fd, "The following skills and spells are race specific.\n");
@@ -1605,8 +1686,8 @@
 		{
 			send_buf(wdesc->fd, "<TD>%d</TD>\n", wch->level);
 			send_buf(wdesc->fd,
-					 "<TD><A href=\"%sraces/%s\">%s</A></TD>\n",
-					 HTTP_URL(), wch->race->name, wch->race->name);
+					 "<TD><A href=\"%s\">%s</A></TD>\n",
+					 HTTP_URL("races/%s", wch->race->name), wch->race->name);
 			send_buf(wdesc->fd, "<TD>%s</TD>\n", class_who(wch));
 		}
 		else
@@ -1619,8 +1700,8 @@
 		{
 			html_colourconv(buf, wch->clan->who_name);
 			send_buf(wdesc->fd,
-					 "<TD><A href=\"%sclans/%s\">%s</A></TD>\n",
-					 HTTP_URL(), wch->clan->name, buf);
+					 "<TD><A href=\"%s\">%s</A></TD>\n",
+					 HTTP_URL("clans/%s", wch->clan->name), buf);
 		}
 		else
 			send_buf(wdesc->fd, "<TD></TD>\n");
@@ -1658,8 +1739,10 @@
 		for (pos = 0; pos < MAX_GAMESTAT; pos++)
 		{
 			send_buf(wdesc->fd,
-					 "<li><A HREF=\"%sstats/%s\">%s</A>\n", HTTP_URL(),
-					 stat_type_name[pos][1], stat_type_name[pos][0]);
+					 "<li><A HREF=\"%s\">%s</A>\n", HTTP_URL("stats/%s",
+															 stat_type_name[pos]
+															 [1]),
+					 stat_type_name[pos][0]);
 		}
 		send_buf(wdesc->fd, "</OL>\n");
 		print_footer(wdesc);
@@ -1671,14 +1754,14 @@
 		{
 			if (!str_cmp(stat_type_name[pos][1], buf))
 			{
-				int count_statlist args((void));
-				int compare_stats args((const void *v1, const void *v2));
+				PROTOTYPE(int count_statlist, (void));
+				PROTOTYPE(int compare_stats, (const void *, const void *));
 				char temp[MSL];
 				STAT_DATA *curr;
 				STAT_DATA **top;
 				int count, loop;
 				bool found = FALSE;
-				extern int compare_type;
+				EXTERN int compare_type;
 
 				sprintf(temp, "Ranking of %s", stat_type_name[pos][0]);
 				print_header(wdesc, temp);
@@ -1724,8 +1807,8 @@
 
 				send_buf(wdesc->fd, "</TABLE>");
 				send_buf(wdesc->fd,
-						 "<BR><A href=\"%sstats\">Back to Stats Index</A>\n",
-						 HTTP_URL());
+						 "<BR><A href=\"%s\">Back to Stats Index</A>\n",
+						 HTTP_URL("stats"));
 				print_footer(wdesc);
 				free_mem(top);
 				return TRUE;
@@ -1757,11 +1840,12 @@
 				break;
 		}
 		if (pHelp)
-			send_buf(wdesc->fd, "%s<TD><A href=\"%shelps/%d\">%s</TD>\n",
-					 (pos == 0) ? "<TR>" : "", HTTP_URL(), count, i->name);
+			send_buf(wdesc->fd, "%s<TD><A href=\"%s\">%s</TD>\n",
+					 (pos == 0) ? "<TR>" : "", HTTP_URL("helps/%d", count),
+					 i->name);
 		else
-			send_buf(wdesc->fd,
-					 "%s<TD>%s</TD>\n", (pos == 0) ? "<TR>" : "", i->name);
+			send_buf(wdesc->fd, "%s<TD>%s</TD>\n", (pos == 0) ? "<TR>" : "",
+					 i->name);
 		if (++pos % 5 == 0)
 		{
 			send_buf(wdesc->fd, "</TR>");
@@ -1800,8 +1884,9 @@
 					wordkey[0] = '\0';
 					temp = one_argument(temp, wordkey);
 					send_buf(wdesc->fd,
-							 "%s<TD><A HREF=\"%shelps/%d\">%s</A></TD>\n",
-							 (pos == 0) ? "<TR>" : "", HTTP_URL(), count,
+							 "%s<TD><A HREF=\"%s\">%s</A></TD>\n",
+							 (pos == 0) ? "<TR>" : "", HTTP_URL("helps/%d",
+																count),
 							 wordkey);
 					if (++pos % 5 == 0)
 					{
@@ -1834,8 +1919,8 @@
 				send_buf(wdesc->fd, "<TR><TD>%s</TD></TR>\n", buf2);
 				send_buf(wdesc->fd, "</TABLE>\n");
 				send_buf(wdesc->fd,
-						 "<BR><A HREF=\"%shelps\">Back to Help Index</A>\n",
-						 HTTP_URL());
+						 "<BR><A HREF=\"%s\">Back to Help Index</A>\n",
+						 HTTP_URL("helps"));
 				print_footer(wdesc);
 				return TRUE;
 			}
@@ -1865,10 +1950,10 @@
 			send_buf(wdesc->fd, "<TR>\n");
 			send_buf(wdesc->fd,
 					 "<TD><A HREF=\"%s"
-					 "races/%s\">%s</A></TD>\n<TD>%d</TD>\n<TD>%d</TD>\n<TD>%d</TD>\n"
+					 "\">%s</A></TD>\n<TD>%d</TD>\n<TD>%d</TD>\n<TD>%d</TD>\n"
 					 "<TD>%d</TD>\n<TD>%d</TD><TD ALIGN=\"center\">%d</TD></TR>\n",
-					 HTTP_URL(),
-					 race->name, race->name,
+					 HTTP_URL("races/%s",
+							  race->name), race->name,
 					 race->max_stats[STAT_STR],
 					 race->max_stats[STAT_INT],
 					 race->max_stats[STAT_WIS],
@@ -1879,8 +1964,8 @@
 		send_buf(wdesc->fd,
 				 "<P>Creation points increase the amount of experience it takes to gain a level. Maximum a stat can go is 30.</P>\n");
 		send_buf(wdesc->fd,
-				 "<P>To view skills and spells available to each race, visit the <a href=\"%sspells#RaceSkills\">Skill/Spell</A> section.</P>\n",
-				 HTTP_URL());
+				 "<P>To view skills and spells available to each race, visit the <a href=\"%s\">Skill/Spell</A> section.</P>\n",
+				 HTTP_URL("spells#RaceSkills"));
 		print_footer(wdesc);
 		return TRUE;
 	}
@@ -1958,9 +2043,10 @@
 		for (i = 0; i < maxClass; i++)
 		{
 			send_buf(wdesc->fd,
-					 "<TR><TD><A HREF=\"%sclass/%s\">%s</A>"
-					 "</TD></TR>\n", HTTP_URL(),
-					 class_table[i].name, class_table[i].name);
+					 "<TR><TD><A HREF=\"%s\">%s</A>"
+					 "</TD></TR>\n", HTTP_URL("class/%s",
+											  class_table[i].name),
+					 class_table[i].name);
 		}
 		send_buf(wdesc->fd, "</TABLE>\n");
 		print_footer(wdesc);
@@ -2038,8 +2124,10 @@
 		for (pos = 0; pos < MAX_BOARD - 1; pos++)
 		{
 			send_buf(wdesc->fd,
-					 "<li><A HREF=\"%snotes/%s\">%s</A>\n", HTTP_URL(),
-					 boards[pos].short_name, boards[pos].short_name);
+					 "<li><A HREF=\"%s\">%s</A>\n", HTTP_URL("notes/%s",
+															 boards
+															 [pos].short_name),
+					 boards[pos].short_name);
 		}
 		send_buf(wdesc->fd, "</OL>\n");
 		print_footer(wdesc);
@@ -2070,8 +2158,8 @@
 							 pnote->sender, pnote->subject, pnote->date, buf2);
 				}
 				send_buf(wdesc->fd,
-						 "<BR><A href=\"%snotes\">Back to Board Index</A>\n",
-						 HTTP_URL());
+						 "<BR><A href=\"%s\">Back to Board Index</A>\n",
+						 HTTP_URL("notes"));
 				print_footer(wdesc);
 				return TRUE;
 			}
@@ -2181,8 +2269,8 @@
 					&& pexit->u1.to_room != NULL)
 				{
 					send_buf(wdesc->fd,
-							 "<TD><A href=\"%srooms/%ld\">%s</A></TD>",
-							 HTTP_URL(), pexit->u1.to_room->vnum,
+							 "<TD><A href=\"%s\">%s</A></TD>",
+							 HTTP_URL("rooms/%ld", pexit->u1.to_room->vnum),
 							 dir_name[door]);
 				}
 				else
@@ -2204,7 +2292,7 @@
 HANDLE_URL(HandleSocialsRequest)
 {
 	SOCIAL_DATA *iSocial;
-	int i;
+	int i = 0;
 
 	print_header(wdesc, "Socials");
 	send_buf(wdesc->fd, "<TABLE><TR>\n");
@@ -2226,11 +2314,11 @@
 		{
 			print_header(wdesc, "Immortal Info Page");
 			send_buf(wdesc->fd,
-					 "<hr><P><A href=\"%sstaffarea/skdebug\">Skill Debug List</A></P>",
-					 HTTP_URL());
+					 "<hr><P><A href=\"%s\">Skill Debug List</A></P>",
+					 HTTP_URL("staffarea/skdebug"));
 			send_buf(wdesc->fd,
-					 "<P><A href=\"%sstaffarea/log\">Log Files</A></P>",
-					 HTTP_URL());
+					 "<P><A href=\"%s\">Log Files</A></P>",
+					 HTTP_URL("staffarea/log"));
 			send_buf(wdesc->fd, "<hr>");
 			print_footer(wdesc);
 			return TRUE;
@@ -2268,8 +2356,8 @@
 			{
 				char buf2[MSL];
 				char *check = get_next(buf);
-				DIR *Directory;
-				struct dirent *Dir;
+				struct dirent **Dir;
+				int o, i;
 
 				if (IS_NULLSTR(check))
 				{
@@ -2278,24 +2366,21 @@
 
 					print_header(wdesc, "Log Files");
 					send_buf(wdesc->fd, "<TABLE><TR>\n");
-					Directory = opendir("../log");
-					Dir = readdir(Directory);
-					while (Dir != NULL)
+					o = scandir(LOG_DIR, &Dir, 0, alphasort);
+					for (i = 0; i != o; i++)
 					{
-						if (!str_suffix(".log", Dir->d_name))
+						if (!str_suffix(".log", Dir[i]->d_name))
 						{
-							strcpy(buff, Dir->d_name);
+							strcpy(buff, Dir[i]->d_name);
 							buff[strlen(buff) - 4] = '\0';
 							send_buf(wdesc->fd,
-									 "%s<TD><A href=\"%s%s/log/%s\">%s</A></TD>\n",
+									 "%s<TD><A href=\"%s\">%s</A></TD>\n",
 									 count % 5 == 0 ? "</TR><TR>" : "",
-									 HTTP_URL(), "staffarea", buff,
-									 Dir->d_name);
+									 HTTP_URL("staffarea/log/%s", buff),
+									 Dir[i]->d_name);
 							count++;
 						}
-						Dir = readdir(Directory);
 					}
-					closedir(Directory);
 					send_buf(wdesc->fd, "%s</TABLE>\n",
 							 count % 5 != 0 ? "</TR>" : "");
 					print_footer(wdesc);
@@ -2303,28 +2388,25 @@
 				}
 				else
 				{
-					Directory = opendir("../log");
-					Dir = readdir(Directory);
-					while (Dir != NULL)
+					o = scandir(LOG_DIR, &Dir, 0, alphasort);
+					for (i = 0; i != o; i++)
 					{
-						if (!str_suffix(".log", Dir->d_name))
+						if (!str_suffix(".log", Dir[i]->d_name))
 						{
-							strcpy(buf2, Dir->d_name);
+							strcpy(buf2, Dir[i]->d_name);
 							buf2[strlen(buf2) - 4] = '\0';
 							if (!str_cmp(buf2, check))
 							{
 								print_header(wdesc, buf2);
 								send_buf(wdesc->fd, "<PRE>\n");
-								sprintf(buf2, "../log/%s", Dir->d_name);
+								sprintf(buf2, LOG_DIR "%s", Dir[i]->d_name);
 								print_file(wdesc, buf2);
 								send_buf(wdesc->fd, "</PRE>\n");
 								print_footer(wdesc);
 								return TRUE;
 							}
 						}
-						Dir = readdir(Directory);
 					}
-					closedir(Directory);
 				}
 				return FALSE;
 			}
@@ -2341,6 +2423,37 @@
 	}
 }
 
+HANDLE_URL(HandleHistoryRequest)
+{
+	int i;
+	bool found = FALSE;
+
+	print_header(wdesc, "Channel History");
+	send_buf(wdesc->fd, "<PRE>\n");
+	for (i = (www_index + 1) % 20; i != www_index; i = (i + 1) % 20)
+	{
+		if (!IS_NULLSTR(www_history[i]))
+		{
+			found = TRUE;
+			send_buf(wdesc->fd, "%s\n", smash_colour(www_history[i]));
+		}
+	}
+	if (!IS_NULLSTR(www_history[www_index]))
+	{
+		send_buf(wdesc->fd, "%s\n", smash_colour(www_history[www_index]));
+		found = TRUE;
+	}
+
+	if (!found)
+		send_buf(wdesc->fd, "None.\n");
+	else
+		send_buf(wdesc->fd, "\nCurrent time: %s.\n",
+				 str_time(current_time, -1, "%I:%M:%S %p"));
+	send_buf(wdesc->fd, "</PRE>");
+	print_footer(wdesc);
+	return TRUE;
+}
+
 HANDLE_URL(HandleIndexRequest)
 {
 	print_header(wdesc, "Welcome");
@@ -2372,6 +2485,7 @@
 	{"commands", "Commands", HandleCommandsRequest, FALSE},
 	{"clans", "Clans", HandleClanRequest, FALSE},
 	{"class", "Classes", HandleClassRequest, FALSE},
+	{"history", "History", HandleHistoryRequest, FALSE},
 	{"stats", "Stats", HandleStatsRequest, FALSE},
 	{"rooms", "Explore", HandleRoomsRequest, FALSE},
 	{"objs", NULL, HandleObjsRequest, FALSE},
diff -ur -x config -x o -x rom src/webserver.h new/webserver.h
--- src/webserver.h	Tue May 27 02:46:36 2003
+++ new/webserver.h	Sun Aug 31 19:23:21 2003
@@ -25,7 +25,10 @@
  *	to be code generated and to format accordingly before and after.
  *
  *	-- Christopher Aaron Haslage (Yakkov) 6/3/99 (No Help)
- */
+***************************************************************************
+*       1stMUD ROM Derivative (c) 2001-2003 by Ryan Jennings              *
+*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
+***************************************************************************/
 
  /* Modded for 1stMUD by Markanth 14/05/2003 */
 
@@ -34,12 +37,6 @@
 
 #if !defined(NO_WEB)
 
-#if !defined(WIN32)
-#include <arpa/inet.h>
-#else
-#include "../win32/winstuff.h"
-#endif
-
 #define DOCTYPE "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
 
 /*
@@ -52,19 +49,15 @@
  */
 
 #define AUTH_DOMAIN     "Staff Area - Username and Password are CASE SENSITIVE."	/* Secure Area Description */
-#define MAXDATA         1024
+#define MAXDATA         MAX_STRING_LENGTH
 
 #define DEFAULT_URL     "http://%s:%d/"
 #define TELNET_URL		"telnet://%s:%d/"
 
 #define WEBSERVERPORT   (port + 5)	// port the web server will run on
 
-#define MUD_NAME        "1stMUD"	// You mud's name here
-
-extern bool WebUP;
-
 /* HTTP Basic Auth req. Base64 encoded/decode */
-void Base64Decode(char *bufcoded, unsigned char *bufplain, int outbufsize);
+PROTOTYPE(void Base64Decode, (char *, unsigned char *, int));
 
 typedef struct web_descriptor WEB_DESCRIPTOR;
 
@@ -73,19 +66,14 @@
 	WEB_DESCRIPTOR *next;
 	WEB_DESCRIPTOR *prev;
 	int fd;
-	char request[MAXDATA * 2];
+	char request[MAXDATA];
 	struct sockaddr_in their_addr;
-#if !defined(__CYGWIN__)
-	unsigned int sin_size;
-#else
-	int sin_size;
-#endif
 	bool valid;
 	bool keepalive;
 };
 
-typedef bool WEB_FUN
-args((WEB_DESCRIPTOR * wdesc, char *path, const char *stuff));
+typedef bool WEB_FUN(WEB_DESCRIPTOR * wdesc, char *path, const char *stuff);
+
 #define HANDLE_URL(fun)	bool fun (WEB_DESCRIPTOR *wdesc, char *path, const char *stuff)
 
 struct request_type
@@ -96,16 +84,15 @@
 	bool secure;
 };
 
-extern const struct request_type request_table[];
+EXTERN const struct request_type request_table[];
 
 /* FUNCTION DEFS */
-int send_buf(int fd, const char *fmt, ...)
-	__attribute__ ((format(printf, 2, 3)));
-void handle_web_request(WEB_DESCRIPTOR * wdesc);
-
-bool init_web_server(void);
-void update_web_server(void);
-void shutdown_web_server(void);
+PROTOTYPEF(int send_buf, (int, const char *, ...), 2, 3);
+PROTOTYPE(void handle_web_request, (WEB_DESCRIPTOR *));
+
+PROTOTYPE(bool init_web_server, (void));
+PROTOTYPE(void update_web_server, (void));
+PROTOTYPE(void shutdown_web_server, (void));
 
 #endif
 #endif