1stMUD/corefiles/
1stMUD/gods/
1stMUD/notes/
1stMUD/player/
1stMUD/win32/
1stMUD/win32/ROM/
diff -ur src/Makefile new/Makefile
--- src/Makefile	Thu Apr 24 12:37:54 2003
+++ new/Makefile	Wed May  7 20:25:00 2003
@@ -2,7 +2,10 @@
 PROF    = -ggdb3
 WARN    = -Wall -Werror
 LIBS	= -lcrypt -lz
-D_FLAGS = -DNO_STRHASH #-DNO_MCCP
+#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)
 
Only in src/: Makefile.linux
Only in src/: Makefile.normal
Only in src/: Makefile.solaris
diff -ur src/act_comm.c new/act_comm.c
--- src/act_comm.c	Sun Apr 27 22:08:24 2003
+++ new/act_comm.c	Thu May  8 14:57:41 2003
@@ -117,7 +117,7 @@
 					  const char *chan, const char *str, int type)
 {
 	int i;
-	char time[MIL];
+	char *time;
 	char buf[MSL];
 
 	if (IS_NPC(viewer) || IS_NULLSTR(str) || IS_NULLSTR(chan) || last < 0
@@ -130,7 +130,7 @@
 					   viewer->pcdata->history[last][i - 1]);
 	}
 
-	strftime(time, 100, "%r", localtime(&current_time));
+	time = str_time(current_time, GET_TZONE(viewer), "%r");
 	switch (type)
 	{
 	case CHANNEL_NORMAL:
@@ -1617,18 +1617,39 @@
 	return;
 }
 
-int find_colour_slot(const char *code)
+int attribute_lookup(const char *arg)
 {
 	int i;
 
-	for (i = 0; colour_chars[i].code != NULL; i++)
-		if (!str_cmp(code, colour_chars[i].code))
+	for (i = 0; colour_attributes[i].name != NULL; i++)
+		if (!str_prefix(arg, colour_attributes[i].name))
 			return i;
 
-	return 0;
+	return -1;
+}
+
+int foreground_lookup(const char *arg)
+{
+	int i;
+
+	for (i = 0; colour_foregrounds[i].name != NULL; i++)
+		if (!str_prefix(arg, colour_foregrounds[i].name))
+			return i;
+
+	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))
+			return i;
+
+	return -1;
 }
 
-/* Sets all or 1 custom colours to default */
 void default_colour(CHAR_DATA * ch, int slot)
 {
 	int i = 0;
@@ -1638,17 +1659,25 @@
 
 	if (slot == -1)
 	{
-		for (i = 0; cslot_table[i].def != NULL; i++)
-			ch->pcdata->colour[cslot_table[i].slot] =
-				find_colour_slot(cslot_table[i].def);
+		for (i = 0; i < MAX_CUSTOM_COLOUR; i++)
+		{
+			ch->pcdata->colour[cslot_table[i].slot][0] =
+				cslot_table[i].col_attr;
+			ch->pcdata->colour[cslot_table[i].slot][1] =
+				cslot_table[i].col_fore;
+			ch->pcdata->colour[cslot_table[i].slot][2] =
+				cslot_table[i].col_back;
+		}
 	}
 	else
 	{
-		for (i = 0; cslot_table[i].def != NULL; i++)
+		for (i = 0; i < MAX_CUSTOM_COLOUR; i++)
 		{
 			if (cslot_table[i].slot == slot)
 			{
-				ch->pcdata->colour[slot] = find_colour_slot(cslot_table[i].def);
+				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;
 				break;
 			}
 		}
@@ -1657,81 +1686,42 @@
 	return;
 }
 
-const char *color_default(CHAR_DATA * ch)
-{
-	int colour;
-
-	if (!ch || IS_NPC(ch))
-		return C_CLEAR;
-
-	colour = ch->pcdata->colour[_DEFAULT];
-
-	if (colour < 0 || colour_chars[colour].code == NULL)
-		return C_CLEAR;
-
-	else if (!str_cmp(colour_chars[colour].code, C_RANDOM))
-		return random_colour();
-
-	else if (!str_cmp(colour_chars[colour].code, RANDOM_BG))
-		return random_background();
-
-	else
-		return colour_chars[ch->pcdata->colour[_DEFAULT]].code;
-}
-
-/* return the players ansi code for a slot */
 const char *char_colour(CHAR_DATA * ch, int slot)
 {
-	int colour;
-
-	if (!ch || IS_NPC(ch) || slot < 0 || slot > MAX_CUSTOM_COLOUR)
-		return C_CLEAR;
-
-	colour = ch->pcdata->colour[slot];
-
-	if (colour < 0 || colour_chars[colour].code == NULL)
-		return C_CLEAR;
-
-	else if (!str_cmp(colour_chars[colour].code, C_RANDOM))
-		return random_colour();
-
-	else if (!str_cmp(colour_chars[colour].code, RANDOM_BG))
-		return random_background();
-
-	else
-		return colour_chars[colour].code;
+	extern int col_attr, col_fore, col_back;
 
-}
-
-/* return a colour number */
-int colour_lookup(const char *arg)
-{
-	int i;
+	if (!ch || !ch->desc || IS_NPC(ch) || slot < 0 || slot >= MAX_CUSTOM_COLOUR)
+	{
+		col_attr = CL_CLEAR;
+		col_fore = FG_NONE;
+		col_back = BG_NONE;
+		return CL_DEFAULT;
+	}
 
-	for (i = 0; colour_chars[i].name != NULL; i++)
-		if (!str_cmp(arg, colour_chars[i].name))
-			return i;
+	col_attr = ch->pcdata->colour[slot][0];
+	col_fore = ch->pcdata->colour[slot][1];
+	col_back = ch->pcdata->colour[slot][2];
 
-	return -1;
+	return make_colour();
 }
 
-/* returns a custom colour number */
 int cslot_lookup(const char *arg)
 {
 	int i;
 
-	for (i = 0; cslot_table[i].name != NULL; i++)
+	for (i = 0; i < MAX_CUSTOM_COLOUR; i++)
 		if (!str_prefix(arg, cslot_table[i].name))
 			return cslot_table[i].slot;
 
 	return -1;
 }
 
-/* sets custom colours */
 CH_CMD(do_colourset)
 {
-	char arg[MIL], arg2[MIL];
-	int i = 0, pos = 0, slot = 0, color = 0;
+	char arg[MIL], attr[MIL], fore[MIL], back[MIL];
+	int i = 0, slot = 0;
+	int c_attr, c_fore, c_back;
+	int pos = 0;
 
 	if (!ch || IS_NPC(ch) || !ch->desc)
 		return;
@@ -1743,15 +1733,16 @@
 	}
 
 	argument = one_argument(argument, arg);
-	argument = one_argument(argument, arg2);
+	argument = one_argument(argument, attr);
+	argument = one_argument(argument, fore);
+	argument = one_argument(argument, back);
 
 	if (IS_NULLSTR(arg))
 	{
-		chprintln
-			(ch,
-			 "Syntax: colourset colours           - lists possible colours");
 		chprintln(ch,
-				  "        colourset options           - lists options to colourize");
+				  "Syntax: colourset colours           - lists possible colours");
+		chprintln(ch,
+				  "        colourset status            - lists options to colourize");
 		chprintln(ch,
 				  "        colourset <option> <colour> - sets an option to a colour");
 		chprintln(ch,
@@ -1760,43 +1751,59 @@
 				  "        colourset default all       - reset all options to default values");
 		return;
 	}
-	if (!str_prefix(arg, "colours") || !str_prefix(arg, "colors"))
+	else if (!str_prefix(arg, "colours") || !str_prefix(arg, "colors"))
 	{
-		chprintln(ch, "Available Colours:");
-		for (i = 0; colour_chars[i].name != NULL; i++)
+		int j = 0, k = 0;
+
+		chprintln(ch, "Attributes       Foregrounds      Backgrounds");
+		chprintln(ch, draw_line(ch, NULL, 58));
+		for (i = 0; colour_attributes[i].name != NULL; i++)
 		{
-			chprintf(ch, "%s%-10s{x", colour_chars[i].code,
-					 colour_chars[i].name);
-			if (++pos % 4 == 0)
-			{
+			chprintf(ch, "%-15s  ", colour_attributes[i].name);
+			if (colour_foregrounds[j].name != NULL)
+				chprintf(ch, "%-15s  ", colour_foregrounds[j++].name);
+			else
+				chprintf(ch, "%-15s  ", " ");
+			if (colour_backgrounds[k].name != NULL)
+				chprintlnf(ch, "%s", colour_backgrounds[k++].name);
+			else
 				chprintln(ch, "");
-				pos = 0;
-			}
 		}
-		if (pos != 0)
-			chprintln(ch, "");
+		while (colour_foregrounds[j].name != NULL)
+		{
+			chprintf(ch, "%-15s  %-15s  ", " ", colour_foregrounds[j++].name);
+			if (colour_backgrounds[k].name != NULL)
+				chprintlnf(ch, "%s", colour_backgrounds[k++].name);
+			else
+				chprintln(ch, "");
+		}
+		while (colour_backgrounds[k].name != NULL)
+			chprintlnf(ch, "%-15s  %-15s  %s", " ", " ",
+					   colour_backgrounds[k++].name);
+		chprintln(ch, draw_line(ch, NULL, 58));
 	}
-	else if (!str_prefix(arg, "options"))
+	else if (!str_prefix(arg, "status"))
 	{
-		chprintln(ch, "Available Options:");
-		for (i = 0; cslot_table[i].name != NULL; i++)
+		chprintln(ch,
+				  "Options that can currently be configured for color are:");
+		chprintln(ch, draw_line(ch, NULL, 58));
+
+		for (i = 0; i < MAX_CUSTOM_COLOUR; i++)
 		{
-			chprintf(ch, "" CTAG(%d) "%-10s{x", cslot_table[i].slot,
-					 cslot_table[i].name);
-			if (++pos % 6 == 0)
-			{
+			chprintf(ch, "%-12s - " CTAG(%d) "Looks like this..{x ",
+					 cslot_table[i].name, cslot_table[i].slot);
+			if (++pos % 2 == 0)
 				chprintln(ch, "");
-				pos = 0;
-			}
 		}
-		if (pos != 0)
+		if (pos % 2 != 0)
 			chprintln(ch, "");
+		chprintln(ch, draw_line(ch, NULL, 58));
 	}
 	else if (!str_prefix(arg, "default"))
 	{
-		if ((slot = cslot_lookup(arg2)) == -1)
+		if ((slot = cslot_lookup(attr)) == -1)
 		{
-			if (!str_cmp(arg2, "all"))
+			if (!str_cmp(attr, "all"))
 				chprintln(ch, "All colour values set to default.");
 			else
 			{
@@ -1805,8 +1812,7 @@
 			}
 		}
 		else
-			chprintf(ch, "%s set to default value.\n\r",
-					 cslot_table[slot].name);
+			chprintlnf(ch, "%s set to default value.", cslot_table[slot].name);
 		default_colour(ch, slot);
 		return;
 	}
@@ -1818,16 +1824,40 @@
 			return;
 		}
 
-		if ((color = colour_lookup(arg2)) == -1)
+		if (IS_NULLSTR(attr) || IS_NULLSTR(fore) || IS_NULLSTR(back))
+		{
+			chprintln
+				(ch,
+				 "Syntax: colourset <option> <attribute> <foreground> <background>");
+			return;
+		}
+
+		if ((c_attr = attribute_lookup(attr)) == -1)
+		{
+			chprintln(ch, "Invalid Colour Attribute.");
+			return;
+		}
+
+		if ((c_fore = foreground_lookup(fore)) == -1)
+		{
+			chprintln(ch, "Invalid Foreground Colour.");
+			return;
+		}
+
+		if ((c_back = background_lookup(back)) == -1)
 		{
-			chprintln(ch, "Invalid Colour.");
+			chprintln(ch, "Invalid background Colour.");
 			return;
 		}
 
-		ch->pcdata->colour[slot] = color;
-		chprintf(ch, "%s%s{x set to %s%s{x.\n\r", char_colour(ch, slot),
-				 cslot_table[slot].name, char_colour(ch, slot),
-				 colour_chars[color].name);
+		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;
+		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,
+				   colour_foregrounds[c_fore].name,
+				   colour_backgrounds[c_back].name);
 		return;
 	}
 }
diff -ur src/act_info.c new/act_info.c
--- src/act_info.c	Sun Apr 27 22:08:24 2003
+++ new/act_info.c	Thu May  8 14:57:41 2003
@@ -91,17 +91,17 @@
 		return buf;
 
 	if (IS_OBJ_STAT(obj, ITEM_INVIS))
-		strcat(buf, "(Invis) ");
+		strcat(buf, "({cInvis{x) ");
 	if (IS_AFFECTED(ch, AFF_DETECT_EVIL) && IS_OBJ_STAT(obj, ITEM_EVIL))
-		strcat(buf, "(Red Aura) ");
+		strcat(buf, "({RRed Aura{x) ");
 	if (IS_AFFECTED(ch, AFF_DETECT_GOOD) && IS_OBJ_STAT(obj, ITEM_BLESS))
-		strcat(buf, "(Blue Aura) ");
+		strcat(buf, "({BBlue Aura{x) ");
 	if (IS_AFFECTED(ch, AFF_DETECT_MAGIC) && IS_OBJ_STAT(obj, ITEM_MAGIC))
-		strcat(buf, "(Magical) ");
+		strcat(buf, "({MMagical{x) ");
 	if (IS_OBJ_STAT(obj, ITEM_GLOW))
-		strcat(buf, "(Glowing) ");
+		strcat(buf, "({YGlowing{x) ");
 	if (IS_OBJ_STAT(obj, ITEM_HUM))
-		strcat(buf, "(Humming) ");
+		strcat(buf, "({CHumming{x) ");
 
 	if (IS_QUESTOR(ch) && (obj->pIndexData->vnum == ch->pcdata->questobj))
 		strcat(buf, "{r[{RTARGET{r]{x ");
@@ -246,31 +246,31 @@
 	buf[0] = '\0';
 
 	if (IS_SET(victim->comm, COMM_AFK))
-		strcat(buf, "[AFK] ");
+		strcat(buf, "{Y[{RAFK{Y]{x ");
 	if (IS_AFFECTED(victim, AFF_INVISIBLE))
-		strcat(buf, "(Invis) ");
+		strcat(buf, "({cInvis{x) ");
 	if (victim->invis_level >= LEVEL_HERO)
-		strcat(buf, "(Wizi) ");
+		strcat(buf, "{c({WWizi{c){x ");
 	if (IS_AFFECTED(victim, AFF_HIDE))
-		strcat(buf, "(Hide) ");
+		strcat(buf, "({DHide{x) ");
 	if (IS_AFFECTED(victim, AFF_CHARM))
-		strcat(buf, "(Charmed) ");
+		strcat(buf, "({MCharmed{x) ");
 	if (IS_AFFECTED(victim, AFF_PASS_DOOR))
-		strcat(buf, "(Translucent) ");
+		strcat(buf, "({cTranslucent{x) ");
 	if (IS_AFFECTED(victim, AFF_FAERIE_FIRE))
-		strcat(buf, "(Pink Aura) ");
+		strcat(buf, "({MPink Aura{x) ");
 	if (IS_EVIL(victim) && IS_AFFECTED(ch, AFF_DETECT_EVIL))
-		strcat(buf, "(Red Aura) ");
+		strcat(buf, "({RRed Aura{x) ");
 	if (IS_GOOD(victim) && IS_AFFECTED(ch, AFF_DETECT_GOOD))
-		strcat(buf, "(Golden Aura) ");
+		strcat(buf, "({YGolden Aura{x) ");
 	if (IS_AFFECTED(victim, AFF_SANCTUARY))
-		strcat(buf, "(White Aura) ");
+		strcat(buf, "({WWhite Aura{x) ");
 	if (!IS_NPC(victim) && IS_SET(victim->act, PLR_WAR))
-		strcat(buf, "(WAR) ");
+		strcat(buf, "({RWAR{x) ");
 	if (!IS_NPC(victim) && IS_SET(victim->act, PLR_KILLER))
-		strcat(buf, "(KILLER) ");
+		strcat(buf, "({rKILLER{x) ");
 	if (!IS_NPC(victim) && IS_SET(victim->act, PLR_THIEF))
-		strcat(buf, "(THIEF) ");
+		strcat(buf, "({rTHIEF{x) ");
 	if (IS_QUESTOR(ch) && IS_NPC(victim)
 		&& (victim->pIndexData->vnum == ch->pcdata->questmob))
 		strcat(buf, "{r[{RTARGET{r]{x ");
@@ -278,7 +278,7 @@
 	if (ON_GQUEST(ch) && IS_NPC(victim)
 		&& is_gqmob(ch, victim->pIndexData->vnum) != -1)
 	{
-		strcat(buf, "(Gquest) ");
+		strcat(buf, "{Y({RGquest{Y){x ");
 	}
 
 	if (victim->position == victim->start_pos && victim->long_descr[0] != '\0')
@@ -967,7 +967,7 @@
 			 (IS_NPC(ch) || IS_SET(ch->act, PLR_HOLYLIGHT))) ||
 			IS_BUILDER(ch, ch->in_room->area))
 		{
-			chprintf(ch, " [Room {R%ld" CTAG(_RTITLE) "]", ch->in_room->vnum);
+			chprintf(ch, " {w[{WRoom {R%ld{w]", ch->in_room->vnum);
 		}
 
 		chprintln(ch, "{x");
@@ -1693,6 +1693,24 @@
 	char *suf;
 	int day;
 
+	if (!IS_NULLSTR(argument))
+	{
+		CHAR_DATA *victim;
+
+		if ((victim = get_char_world(ch, argument)) == NULL || IS_NPC(victim))
+		{
+			chprintln(ch, "There is no such player.");
+			return;
+		}
+		if (GET_TZONE(victim) == -1)
+		{
+			act("$N doesn't have a time zone set.", ch, NULL, victim, TO_CHAR);
+			return;
+		}
+		act("{W$N's local time is $t.{x", ch,
+			str_time(current_time, GET_TZONE(victim), NULL), victim, TO_CHAR);
+		return;
+	}
 	day = time_info.day + 1;
 
 	if (day > 4 && day < 20)
@@ -1712,11 +1730,54 @@
 			   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, (char *) ctime(&current_time));
+			   str_boot_time, str_time(current_time, -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.");
 
 	return;
 }
 
+CH_CMD(do_timezone)
+{
+	int i;
+
+	if (IS_NPC(ch))
+		return;
+
+	if (IS_NULLSTR(argument))
+	{
+		chprintlnf(ch, "%-6s %-29s (%s)", "Name", "City/Zone Crosses", "Time");
+		chprintln(ch, draw_line(ch, NULL, 0));
+		for (i = 0; i < MAX_TZONE; i++)
+		{
+			chprintlnf(ch, "%-6s %-29s (%s)", tzone_table[i].name,
+					   tzone_table[i].zone, str_time(current_time, i, NULL));
+		}
+		chprintln(ch, draw_line(ch, NULL, 0));
+		return;
+	}
+
+	i = tzone_lookup(argument);
+
+	if (i == -1)
+	{
+		chprintln
+			(ch,
+			 "That time zone does not exists. Make sure to use the exact name.");
+		return;
+	}
+
+	ch->pcdata->timezone = i;
+	chprintlnf(ch, "Your time zone is now %s %s (%s)", tzone_table[i].name,
+			   tzone_table[i].zone, str_time(current_time, i, NULL));
+}
+
 CH_CMD(do_weather)
 {
 
@@ -1740,8 +1801,6 @@
 	return;
 }
 
-#define HELP_LOG  "help.log"
-
 /* 
     Syntax(s):
                 help <letter>       - list help files that start with <letter>
@@ -1849,7 +1908,6 @@
 				"No help found for %s. Try using just the first letter.\n\r",
 				nohelp);
 		add_buf(buffer, buf);
-		append_file(ch, HELP_LOG, nohelp);
 		sprintf(log_buf, "Missing Help: %s", nohelp);
 		wiznet(log_buf, ch, NULL, 0, 0, 0);
 	}
diff -ur src/act_obj.c new/act_obj.c
--- src/act_obj.c	Sun Apr 27 22:08:24 2003
+++ new/act_obj.c	Thu May  8 14:57:41 2003
@@ -3191,10 +3191,7 @@
 void save_donation_pit(void)
 {
 	OBJ_DATA *pit;
-	FILE *fp;
-#if !defined(WIN32)
-	char *TEMPFILE = PIT_FILE ".tmp";
-#endif
+	FILE_DATA *fp;
 
 	for (pit = object_first; pit; pit = pit->next)
 	{
@@ -3205,21 +3202,14 @@
 	if (!pit)
 		return;
 
-#if defined(WIN32)
-	if ((fp = file_open(PIT_FILE, "w")) != NULL)
-#else
-	if ((fp = file_open(TEMPFILE, "w")) != NULL)
-#endif
+	if ((fp = fopen_temp(PIT_FILE)) != NULL)
 	{
 		if (pit->first_content)
-			fwrite_obj(NULL, pit->first_content, fp, 0, "P");
-		fprintf(fp, "#END\n");
-		fflush(fp);
+			fwrite_obj(NULL, pit->first_content, fp->file, 0, "P");
+		fprintf(fp->file, "#END\n");
+		fflush(fp->file);
+		fclose_temp(fp);
 	}
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, PIT_FILE);
-#endif
 }
 
 void load_donation_pit(void)
diff -ur src/act_wiz.c new/act_wiz.c
--- src/act_wiz.c	Sun Apr 27 22:08:24 2003
+++ new/act_wiz.c	Thu May  8 14:57:41 2003
@@ -4392,7 +4392,7 @@
 }
 
 /* This file holds the copyover data */
-#define COPYOVER_FILE "copyover.data"
+#define COPYOVER_FILE   DATA_DIR "copyover.dat"
 
 /* This is the executable file */
 #define EXE_FILE	  "../src/rom"
@@ -4423,9 +4423,11 @@
 		return;
 	}
 
+	set_vtimer(-1);
+
 	/* Consider changing all saved areas here, if you use OLC */
 
-	do_asave(NULL, "");
+	do_asave(NULL, "changed");
 
 	save_gquest_data();
 
@@ -4487,7 +4489,9 @@
 
 	fclose(fpReserve);
 
+#if !defined(NO_WEB)
 	shutdown_web_server();
+#endif
 
 	/* exec - descriptors are inherited */
 
@@ -4518,6 +4522,8 @@
 	bool fOld;
 
 	logf("Copyover recovery initiated");
+
+	set_vtimer(-1);
 
 	fp = file_open(COPYOVER_FILE, "r");
 
diff -ur src/ansi.h new/ansi.h
--- src/ansi.h	Sun Apr 27 22:08:25 2003
+++ new/ansi.h	Thu May  8 14:57:42 2003
@@ -32,49 +32,44 @@
 #define	ANSI_CUSTOM     '\x11'
 #define ANSI_END	    '\x12'
 
-#define	C_BLANK         "\x01B[%d;%dm"
-#define	C_REVERSE       "\x01B[7m"
-#define	C_FLASH         "\x01B[5m"
-#define	C_UNDERSCORE    "\x01B[4m"
-#define	C_TILDE         '~'
-#define	C_BEEP          '\a'
+#define FG_BLACK		30
+#define FG_RED			31
+#define FG_GREEN		32
+#define FG_YELLOW		33
+#define FG_BLUE			34
+#define FG_MAGENTA		35
+#define FG_CYAN			36
+#define FG_WHITE		37
+#define FG_RANDOM       -1
+#define FG_NONE         0
 
-#define	C_BLACK         "\x01B[0;30m"
-#define	C_RED           "\x01B[0;31m"
-#define	C_GREEN         "\x01B[0;32m"
-#define	C_YELLOW        "\x01B[0;33m"
-#define	C_BLUE          "\x01B[0;34m"
-#define	C_MAGENTA       "\x01B[0;35m"
-#define	C_CYAN          "\x01B[0;36m"
-#define	C_WHITE         "\x01B[0;37m"
-#define	CB_BLACK        "\x01B[1;30m"
-#define	CB_RED          "\x01B[1;31m"
-#define	CB_GREEN        "\x01B[1;32m"
-#define	CB_YELLOW       "\x01B[1;33m"
-#define	CB_BLUE         "\x01B[1;34m"
-#define	CB_MAGENTA      "\x01B[1;35m"
-#define	CB_CYAN         "\x01B[1;36m"
-#define	CB_WHITE        "\x01B[1;37m"
-#define	C_CLEAR         "\x01B[0m"
-#define C_RANDOM        "{`"
+#define BG_BLACK		40
+#define BG_RED			41
+#define BG_GREEN		42
+#define BG_YELLOW		43
+#define BG_BLUE			44
+#define BG_MAGENTA		45
+#define BG_CYAN			46
+#define BG_WHITE		47
+#define BG_RANDOM       -1
+#define BG_NONE         0
 
-#define	RED_BG          "\x01B[0;41m"
-#define	BLUE_BG         "\x01B[0;44m"
-#define	GREEN_BG        "\x01B[0;42m"
-#define	BLACK_BG        "\x01B[0;40m"
-#define	WHITE_BG        "\x01B[0;47m"
-#define	MAGENTA_BG      "\x01B[0;45m"
-#define	YELLOW_BG       "\x01B[0;43m"
-#define	CYAN_BG         "\x01B[0;46m"
-#define	RED_BBG         "\x01B[1;41m"
-#define	BLUE_BBG        "\x01B[1;44m"
-#define	GREEN_BBG       "\x01B[1;42m"
-#define	BLACK_BBG       "\x01B[1;40m"
-#define	WHITE_BBG       "\x01B[1;47m"
-#define	MAGENTA_BBG     "\x01B[1;45m"
-#define	YELLOW_BBG      "\x01B[1;43m"
-#define	CYAN_BBG        "\x01B[1;46m"
-#define RANDOM_BG       "{="
+#define CL_CLEAR		 0
+#define CL_BRIGHT		 1
+#define CL_DIM			 2
+#define CL_STANDOUT      3
+#define CL_UNDER		 4
+#define CL_BLINK		 5
+#define CL_ITALIC        6
+#define CL_REVERSE		 7
+#define CL_HIDDEN		 8
+#define CL_RANDOM        -1
+
+#define CL_DEFAULT		"\033[0m"
+
+#define CL_FORMAT1      "\033[%dm"
+#define CL_FORMAT2      "\033[%d;%dm"
+#define CL_FORMAT3      "\033[%d;%d;%dm"
 
 #define ALIGN_NONE   0
 #define ALIGN_LEFT   1
diff -ur src/automap.c new/automap.c
--- src/automap.c	Sun Apr 27 22:08:24 2003
+++ new/automap.c	Thu May  8 14:57:41 2003
@@ -500,6 +500,7 @@
 			}
 			while (!alldesc);
 		}
+		strcat(buf, "{x");
 		chprintln(ch, buf);
 	}
 }
diff -ur src/board.c new/board.c
--- src/board.c	Sun Apr 27 22:08:24 2003
+++ new/board.c	Thu May  8 14:57:41 2003
@@ -242,14 +242,15 @@
 /* save a single board */
 static void save_board(BOARD_DATA * board)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	char filename[200];
 	char buf[200];
 	NOTE_DATA *note;
 
 	sprintf(filename, "%s/%s", NOTE_DIR, board->short_name);
 
-	fp = file_open(filename, "w");
+	fp = fopen_temp(filename);
+
 	if (!fp)
 	{
 		sprintf(buf, "Error writing to: %s", filename);
@@ -258,9 +259,9 @@
 	else
 	{
 		for (note = board->note_first; note; note = note->next)
-			append_note(fp, note);
+			append_note(fp->file, note);
 
-		file_close(fp);
+		fclose_temp(fp);
 	}
 }
 
@@ -451,7 +452,6 @@
 /* Start writing a note */
 static void do_nwrite(CHAR_DATA * ch, const char *argument)
 {
-	char *strtime;
 	char buf[200];
 
 	if (IS_NPC(ch))				/* NPC cannot post notes */
@@ -479,11 +479,8 @@
 		ch->pcdata->in_progress = new_note();
 		ch->pcdata->in_progress->sender = str_dup(ch->name);
 
-		/* convert to ascii. ctime returns a string which last character is \n, so remove that */
-		strtime = ctime(&current_time);
-		strtime[strlen(strtime) - 1] = '\0';
-
-		ch->pcdata->in_progress->date = str_dup(strtime);
+		ch->pcdata->in_progress->date =
+			str_dup(str_time(current_time, -1, NULL));
 	}
 
 	act("{G$n starts writing a note.{x", ch, NULL, NULL, TO_ROOM);
@@ -532,8 +529,8 @@
 		chprintlnf(ch,
 				   "{YTo{x:      %s\n\r" "{YExpires{x: %s\n\r"
 				   "{YSubject{x: %s", ch->pcdata->in_progress->to_list,
-				   ctime(&ch->pcdata->in_progress->expire),
-				   ch->pcdata->in_progress->subject);
+				   str_time(ch->pcdata->in_progress->expire, GET_TZONE(ch),
+							NULL), ch->pcdata->in_progress->subject);
 		chprintln(ch, "{GYour note so far:{x");
 		chprint(ch, ch->pcdata->in_progress->text);
 
@@ -687,6 +684,25 @@
 	}
 }
 
+CH_CMD(do_ncheck)
+{
+	int i, count = 0, unread = 0;
+
+	for (i = 0; i < MAX_BOARD; i++)
+	{
+		unread = unread_notes(ch, &boards[i]);
+		if (unread != BOARD_NOACCESS)
+			count += unread;
+	}
+
+	if (count < 1)
+		chprintln(ch, "You have no new notes on the board.");
+	else
+		chprintlnf(ch,
+				   "You have {Y%d{x unread note%s on the board. Type 'board'.",
+				   count, (count != 1) ? "s" : "");
+}
+
 /* Dispatch function for backwards compatibility */
 CH_CMD(do_note)
 {
@@ -717,6 +733,8 @@
 
 	else if (!str_cmp(arg, "catchup"))
 		do_ncatchup(ch, argument);
+	else if (!str_cmp(arg, "check"))
+		do_ncheck(ch, argument);
 	else
 		do_oldhelp(ch, "note");
 }
@@ -839,7 +857,6 @@
 	int board_index = board_lookup(board_name);
 	BOARD_DATA *board;
 	NOTE_DATA *note;
-	char *strtime;
 
 	if (board_index == BOARD_NOTFOUND)
 	{
@@ -863,11 +880,7 @@
 	note->expire = current_time + expire_days * 60 * 60 * 24;
 	note->text = str_dup(text);
 
-	/* convert to ascii. ctime returns a string which last character is \n, so remove that */
-	strtime = ctime(&current_time);
-	strtime[strlen(strtime) - 1] = '\0';
-
-	note->date = str_dup(strtime);
+	note->date = str_dup(str_time(current_time, -1, NULL));
 
 	finish_note(board, note);
 
@@ -1010,8 +1023,9 @@
 		{
 			ch->pcdata->in_progress->expire =
 				current_time + ch->pcdata->board->purge_days * 24L * 3600L;
-			sprintf(buf, "This note will expire %s\r",
-					ctime(&ch->pcdata->in_progress->expire));
+			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"
@@ -1063,8 +1077,6 @@
 	expire = current_time + (days * 24L * 3600L);	/* 24 hours, 3600 seconds */
 
 	ch->pcdata->in_progress->expire = expire;
-
-	/* note that ctime returns XXX\n so we only need to add an \r */
 
 	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"
diff -ur src/comm.c new/comm.c
--- src/comm.c	Sun Apr 27 22:08:24 2003
+++ new/comm.c	Thu May  8 14:57:41 2003
@@ -55,7 +55,11 @@
 #include <ctype.h>
 #include <errno.h>
 #include <stdio.h>
+#define __USE_GNU				/* for strsignal() */
+#define _GNU_SOURCE
 #include <string.h>
+#undef __USE_GNU
+#undef _GNU_SOURCE
 #include <stdlib.h>
 #include <time.h>
 #include <stdarg.h>				/* chprintf */
@@ -88,7 +92,10 @@
 /* Needs to be global because of do_copyover */
 int port, control;
 /* Global variable */
+#if !defined(WIN32) && !defined(__CYGWIN__)
 volatile sig_atomic_t crashed = 0;	/* Are we currently crashing? */
+struct itimerval vtimer;
+#endif
 
 #if	defined( WIN32 )
 #define WOULD_HAVE_BLOCKED ( WSAGetLastError() == WSAEWOULDBLOCK )
@@ -114,45 +121,117 @@
 void set_game_levels args((int Old, int New));
 void save_helps args((void));
 
+void set_vtimer(long sec)
+{
+#if !defined(WIN32) && !defined(__CYGWIN__)
+#define DEFAULT_VTIMER  (60 * 60 * 3)	// 3 minutes
+	vtimer.it_value.tv_sec = sec == -1 ? DEFAULT_VTIMER : sec;
+	vtimer.it_value.tv_usec = 0;
+
+	if (setitimer(ITIMER_VIRTUAL, &vtimer, NULL) < 0)
+	{
+		log_string("Failed to set vtimer.");
+		exit(1);
+	}
+#endif
+}
+
 #if !defined(WIN32)
 #if !defined(__CYGWIN__)
+
+void sigvalarm(int sig)
+{
+	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;
+
+	case 2:
+		break;
+	}
+
+	/* Reboot the MUD */
+
+	set_vtimer(-1);
+
+	halt_mud(sig);				// Shouldn't return
+
+	exit(1);					// Last resort
+}
+
 // Stop an endless loop 
-// Uses alarm() to check for game clock advance every 300 seconds.  If more
-// than 240 seconds of realtime has elapsed, assume loop and conduct a copyover.
 static void sigalrm(int sig)
 {
+	static int attempt = 0;
 	time_t ptm;
+
 	time(&ptm);
 	log_string("TOCK!");
 
-	if ((ptm - current_time) > 240)
+	if ((ptm - current_time) > 200 || crashed)
 	{
-		logf("Looping - Last Command: %s\r", last_command);
-		// this requires you to add an "if (ch)" before the chprint
-		// statements in do_copyover.
-		do_copyover(NULL, "");
-		exit(1);
+		if (attempt != 1)
+		{
+			attempt = 1;		// Try to reboot once...
+
+			halt_mud(sig);		// Should NOT return
+		}
+
+		raise(SIGSEGV);			// Something's wrong, cause a crash
+		exit(0);
 	}
-	alarm(300);
 }
-#endif
-#else
-void gettimeofday(struct timeval *t, void *tz)
+
+struct sigaction halt_action, ignore_action, alarm_action, valarm_action;
+
+struct signal_type
 {
-	struct timeb timebuffer;
-	ftime(&timebuffer);
-	t->tv_sec = timebuffer.time;
-	t->tv_usec = timebuffer.millitm * 1000;
-}
+	int signum;
+	struct sigaction *act;
+	const char *name;			// not used, strsignal() prefered.
+	const char *desc;			// not used, strsignal() prefered.
+};
 
-#endif
+const struct signal_type signal_table[] = {
 
-int main(int argc, char **argv)
+	{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)"},
+	{SIGALRM, &alarm_action, "SIGALRM", "Timer signal from alarm(2)"},
+	{SIGVTALRM, &valarm_action, "SIGVTALRM", "Virtual alarm clock"},
+	{-1, NULL, NULL, NULL}
+};
+
+void set_signals(void)
 {
-	struct timeval now_time;
-#if !defined(WIN32) && !defined(__CYGWIN__)
-	bool fCopyOver = FALSE;
-	struct sigaction halt_action, ignore_action, alarm_action;
+	int i;
 
 	halt_action.sa_handler = halt_mud;
 	sigemptyset(&halt_action.sa_mask);
@@ -166,27 +245,45 @@
 	sigemptyset(&alarm_action.sa_mask);
 	alarm_action.sa_flags = SA_NOMASK;
 
-	sigaction(SIGPIPE, &ignore_action, NULL);	/* who cares about pipes? */
-	sigaction(SIGCHLD, &ignore_action, NULL);	/* stop zombie processes */
-	sigaction(SIGHUP, &ignore_action, NULL);	/* stay alive if user quits */
-	sigaction(SIGINT, &halt_action, NULL);	/* interrupted at keyboard */
-	sigaction(SIGQUIT, &halt_action, NULL);	/* quit at keyboard */
-	sigaction(SIGILL, &halt_action, NULL);	/* illegal instruction */
-	sigaction(SIGFPE, &halt_action, NULL);	/* floating point error */
-	sigaction(SIGSEGV, &halt_action, NULL);	/* invalid memory reference */
-	sigaction(SIGTERM, &halt_action, NULL);	/* terminate */
-	sigaction(SIGBUS, &halt_action, NULL);	/* out of memory?? */
-	sigaction(SIGALRM, &alarm_action, NULL);	/* endless loop check */
+	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);
+
+	vtimer.it_interval.tv_sec = 60;
+	vtimer.it_interval.tv_usec = 0;
+	set_vtimer(-1);
+}
 
-	alarm(300);
+#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;
+}
+#endif
+
+int main(int argc, char **argv)
+{
+	struct timeval now_time;
+#if !defined(WIN32) && !defined(__CYGWIN__)
+	bool fCopyOver = FALSE;
+
+	set_signals();
 #endif
 
 	/*
 	 * Init time.
 	 */
+	tzset();
 	gettimeofday(&now_time, NULL);
 	current_time = (time_t) now_time.tv_sec;
-	strcpy(str_boot_time, ctime(&current_time));
+	strcpy(str_boot_time, str_time(current_time, -1, NULL));
 
 	/*
 	 * Reserve one channel for our use.
@@ -264,7 +361,9 @@
 	if (!fCopyOver)
 #endif
 		control = init_socket(port);
+#if !defined(NO_WEB)
 	WebUP = init_web_server();
+#endif
 	boot_db();
 	sprintf(log_buf, "ROM is ready to rock on port %d.", port);
 	log_string(log_buf);
@@ -273,7 +372,9 @@
 		copyover_recover();
 #endif
 	game_loop(control);
+#if !defined(NO_WEB)
 	shutdown_web_server();
+#endif
 	close(control);
 
 	/*
@@ -432,15 +533,14 @@
 
 void game_loop(int ctrl)
 {
-	static struct timeval null_time;
-	struct timeval last_time;
+	static struct timeval null_time = { 0, 0 };
+	int vt_set = 0;
 
 #if !defined(WIN32)
 	signal(SIGPIPE, SIG_IGN);
 	signal(SIGCHLD, SIG_IGN);
 #endif
-	gettimeofday(&last_time, NULL);
-	current_time = (time_t) last_time.tv_sec;
+	SynchronizeClock();
 
 	/* Main loop */
 	while (!merc_down)
@@ -537,6 +637,9 @@
 				d->fcommand = TRUE;
 				stop_idling(d->character);
 
+				vt_set = 0;
+				set_vtimer(60);
+
 				/* OLC */
 				if (d->showstr_point)
 					show_string(d, d->incomm);
@@ -563,8 +666,10 @@
 		 */
 		update_handler();
 
+#if !defined(NO_WEB)
 		if (WebUP)
 			update_web_server();
+#endif
 
 		/*
 		 * Output.
@@ -608,6 +713,12 @@
 		 */
 		WaitForPulse();
 		SynchronizeClock();
+		if (++vt_set >= 35)
+		{
+			vt_set = 0;
+
+			set_vtimer(60);
+		}
 	}
 
 	return;
@@ -1036,84 +1147,57 @@
 	return;
 }
 
-char *random_colour(void)
+int col_attr, col_fore, col_back;
+
+int random_attr(void)
+{
+	if (number_range(1, 50) < 25)
+		return CL_CLEAR;
+	else
+		return CL_BRIGHT;
+}
+
+int random_fore(void)
 {
-	switch (number_range(1, 14))
-	{
-	case 1:
-		return C_BLUE;
-	case 2:
-		return C_CYAN;
-	case 3:
-		return C_GREEN;
-	case 4:
-		return C_MAGENTA;
-	case 5:
-		return C_RED;
-	case 6:
-		return C_YELLOW;
-	case 7:
-		return CB_BLUE;
-	case 8:
-		return CB_CYAN;
-	case 9:
-		return CB_GREEN;
-	case 10:
-		return CB_MAGENTA;
-	case 11:
-		return CB_WHITE;
-	case 12:
-		return CB_RED;
-	case 13:
-		return C_WHITE;
-	case 14:
-		return CB_YELLOW;
-	default:
-		return C_CLEAR;
-	}
+	return number_range(FG_BLACK, FG_WHITE);
 }
 
-char *random_background(void)
+int random_back(void)
 {
-	switch (number_range(0, 13))
-	{
-	case 0:
-		return BLACK_BG;
-	case 1:
-		return BLUE_BG;
-	case 2:
-		return CYAN_BG;
-	case 3:
-		return GREEN_BG;
-	case 4:
-		return MAGENTA_BG;
-	case 5:
-		return RED_BG;
-	case 6:
-		return YELLOW_BG;
-	case 7:
-		return BLUE_BBG;
-	case 8:
-		return CYAN_BBG;
-	case 9:
-		return GREEN_BBG;
-	case 10:
-		return MAGENTA_BBG;
-	case 12:
-		return RED_BBG;
-	case 13:
-		return YELLOW_BBG;
-	default:
-		return BLACK_BBG;
-	}
+	return number_range(BG_BLACK, BG_WHITE);
+}
+
+char *make_colour(void)
+{
+	bool a, b;
+
+	if (col_attr == CL_RANDOM)
+		col_attr = random_attr();
+	if (col_fore == FG_RANDOM)
+		col_fore = random_fore();
+	if (col_back == BG_RANDOM)
+		col_back = random_back();
+
+	a = (col_fore != FG_NONE);
+	b = (col_back != BG_NONE);
+
+	if (!a && !b)
+		return FORMATF(CL_FORMAT1, col_attr);
+	else if (a && !b)
+		return FORMATF(CL_FORMAT2, col_attr, col_fore);
+	else if (!a && b)
+		return FORMATF(CL_FORMAT2, col_attr, col_back);
+	else
+		return FORMATF(CL_FORMAT3, col_attr, col_fore, col_back);
 }
 
-/* Taken from Gary McNickel's WOTmud */
+/* Taken from Gary McNickel's WOTmud 
+   Updated by Markanth */
 bool process_ansi_output(DESCRIPTOR_DATA * d)
 {
 	CHAR_DATA *ch;
 	char *counter;
-	char output[MSL];
+	char output[MSL * 10];
 	char temp[MSL];
 	char *work;
 	bool success = TRUE;
@@ -1124,13 +1208,13 @@
 
 	ch = (d->original ? d->original : d->character);
 
-	memset(output, 0, MSL);
+	memset(output, 0, sizeof(output));
 	counter = output;
 	work = d->outbuf;
 
 	while (*work != '\0' && (work - d->outbuf) < d->outtop)
 	{
-		if ((int) (counter - output) >= MSL - 32)
+		if ((long) (counter - output) >= MSL - 32)
 		{
 
 			*counter++ = '\0';
@@ -1138,7 +1222,7 @@
 			if (!(success = write_to_descriptor(d, output, strlen(output))))
 				break;
 
-			memset(output, 0, MSL);
+			memset(output, 0, sizeof(output));
 			counter = output;
 
 		}
@@ -1160,138 +1244,137 @@
 				case ' ':
 					sprintf(temp, "%c ", ANSI_KEY);
 					break;
-				case 'x':
-				case 'X':
-					strcpy(temp, color_default(ch));
-					break;
-				case 'v':
-				case 'V':
-					strcpy(temp, C_REVERSE);
-					break;
-				case 'u':
-				case 'U':
-					strcpy(temp, C_UNDERSCORE);
-					break;
-				case 'f':
-				case 'F':
-					strcpy(temp, C_FLASH);
-					break;
-				case 'b':
-					strcpy(temp, C_BLUE);
-					break;
-				case 'c':
-					strcpy(temp, C_CYAN);
-					break;
-				case 'g':
-					strcpy(temp, C_GREEN);
-					break;
-				case 'm':
-					strcpy(temp, C_MAGENTA);
-					break;
-				case 'd':
-					strcpy(temp, C_BLACK);
-					break;
-				case 'r':
-					strcpy(temp, C_RED);
-					break;
-				case 'y':
-					strcpy(temp, C_YELLOW);
-					break;
-				case 'w':
-					strcpy(temp, C_WHITE);
-					break;
-				case 'B':
-					strcpy(temp, CB_BLUE);
-					break;
-				case 'C':
-					strcpy(temp, CB_CYAN);
-					break;
-				case 'G':
-					strcpy(temp, CB_GREEN);
-					break;
-				case 'M':
-					strcpy(temp, CB_MAGENTA);
-					break;
-				case 'D':
-					strcpy(temp, CB_BLACK);
-					break;
-				case 'R':
-					strcpy(temp, CB_RED);
-					break;
-				case 'W':
-					strcpy(temp, CB_WHITE);
-					break;
-				case 'Y':
-					strcpy(temp, CB_YELLOW);
-					break;
-				case '`':
-					strcpy(temp, random_colour());
-					break;
-				case '1':
-					strcpy(temp, RED_BG);
-					break;
-				case '2':
-					strcpy(temp, BLUE_BG);
-					break;
-				case '3':
-					strcpy(temp, GREEN_BG);
-					break;
-				case '4':
-					strcpy(temp, BLACK_BG);
-					break;
-				case '5':
-					strcpy(temp, WHITE_BG);
-					break;
-				case '6':
-					strcpy(temp, MAGENTA_BG);
-					break;
-				case '7':
-					strcpy(temp, YELLOW_BG);
-					break;
-				case '8':
-					strcpy(temp, CYAN_BG);
-					break;
-				case '!':
-					strcpy(temp, RED_BBG);
-					break;
-				case '@':
-					strcpy(temp, BLUE_BBG);
-					break;
-				case '#':
-					strcpy(temp, GREEN_BBG);
-					break;
-				case '$':
-					strcpy(temp, BLACK_BBG);
-					break;
-				case '%':
-					strcpy(temp, WHITE_BBG);
-					break;
-				case '^':
-					strcpy(temp, MAGENTA_BBG);
-					break;
-				case '&':
-					strcpy(temp, YELLOW_BBG);
-					break;
-				case '*':
-					strcpy(temp, CYAN_BBG);
-					break;
-				case '+':
-				case '=':
-					strcpy(temp, random_background());
-					break;
 				case '-':
-					sprintf(temp, "%c", C_TILDE);
+					strcpy(temp, "~");
 					break;
 				case 'P':
 				case 'p':
-					sprintf(temp, "%c", C_BEEP);
+					sprintf(temp, "%c", 007);
 					break;
 				case ANSI_KEY:
 					sprintf(temp, "%c", ANSI_KEY);
 					break;
 				default:
-					strcpy(temp, C_CLEAR);
-					break;
+					{
+						switch (*work)
+						{
+						case 'x':
+						case 'X':
+							strcpy(temp, char_colour(ch, _DEFAULT));
+							break;
+						case 'v':
+						case 'V':
+							col_attr = CL_REVERSE;
+							break;
+						case 'u':
+						case 'U':
+							col_attr = CL_UNDER;
+							break;
+						case 'f':
+						case 'F':
+							col_attr = CL_BLINK;
+							break;
+						case 'b':
+							col_attr = CL_CLEAR;
+							col_fore = FG_BLUE;
+							break;
+						case 'c':
+							col_attr = CL_CLEAR;
+							col_fore = FG_CYAN;
+							break;
+						case 'g':
+							col_attr = CL_CLEAR;
+							col_fore = FG_GREEN;
+							break;
+						case 'm':
+							col_attr = CL_CLEAR;
+							col_fore = FG_MAGENTA;
+							break;
+						case 'd':
+							col_attr = CL_CLEAR;
+							col_fore = FG_BLACK;
+							break;
+						case 'r':
+							col_attr = CL_CLEAR;
+							col_fore = FG_RED;
+							break;
+						case 'y':
+							col_attr = CL_CLEAR;
+							col_fore = FG_YELLOW;
+							break;
+						case 'w':
+							col_attr = CL_CLEAR;
+							col_fore = FG_WHITE;
+							break;
+						case 'B':
+							col_attr = CL_BRIGHT;
+							col_fore = FG_BLUE;
+							break;
+						case 'C':
+							col_attr = CL_BRIGHT;
+							col_fore = FG_CYAN;
+							break;
+						case 'G':
+							col_attr = CL_BRIGHT;
+							col_fore = FG_GREEN;
+							break;
+						case 'M':
+							col_attr = CL_BRIGHT;
+							col_fore = FG_MAGENTA;
+							break;
+						case 'D':
+							col_attr = CL_BRIGHT;
+							col_fore = FG_BLACK;
+							break;
+						case 'R':
+							col_attr = CL_BRIGHT;
+							col_fore = FG_RED;
+							break;
+						case 'W':
+							col_attr = CL_BRIGHT;
+							col_fore = FG_WHITE;
+							break;
+						case 'Y':
+							col_attr = CL_BRIGHT;
+							col_fore = FG_YELLOW;
+							break;
+						case '`':
+							col_attr = CL_RANDOM;
+							col_fore = FG_RANDOM;
+							break;
+						case '1':
+							col_back = BG_RED;
+							break;
+						case '2':
+							col_back = BG_BLUE;
+							break;
+						case '3':
+							col_back = BG_GREEN;
+							break;
+						case '4':
+							col_back = BG_BLACK;
+							break;
+						case '5':
+							col_back = BG_WHITE;
+							break;
+						case '6':
+							col_back = BG_MAGENTA;
+							break;
+						case '7':
+							col_back = BG_YELLOW;
+							break;
+						case '8':
+							col_back = BG_CYAN;
+							break;
+						case '+':
+						case '=':
+							col_attr = CL_RANDOM;
+							col_back = BG_RANDOM;
+							break;
+						}
+						strcpy(temp, make_colour());
+						break;
+					}
 				}
 			}
 			work++;
@@ -1321,7 +1404,10 @@
 			if (slot < 0 || slot >= MAX_CUSTOM_COLOUR)
 			{
 				bug("ansi_output: invalid custom color", 0);
-				strcpy(temp, C_CLEAR);
+				strcpy(temp, CL_DEFAULT);
+				col_attr = CL_CLEAR;
+				col_fore = FG_NONE;
+				col_back = BG_NONE;
 			}
 			else if (DESC_FLAGGED(d, DESC_COLOUR) &&
 					 (!ch || !IS_SET(ch->comm, COMM_NOCOLOUR)))
@@ -2626,14 +2712,16 @@
 	struct sigaction default_action;
 	int i;
 	pid_t forkpid;
+	int status;
 
-	wait(NULL);
+	waitpid(-1, &status, WNOHANG);
 	if (!crashed)
 	{
 		crashed++;
-		logf("GAME CRASHED (SIGNAL %d).\nLast command: %s", sig, last_command);
+		logf("GAME CRASHED (SIGNAL %d, %s).", sig, strsignal(sig));
+		logf("Last command: %s", last_command);
 		// Inform last command typer that he caused the crash
-		if (strlen(last_command2))
+		if (!IS_NULLSTR(last_command2))
 		{
 			write_to_descriptor(last_descriptor,
 								"\n\rThe last command you typed, '", 0);
@@ -2654,6 +2742,12 @@
 			}
 			if (IS_NPC(ch))
 				continue;
+
+			if ((sig == SIGVTALRM || sig == SIGALRM)
+				&& get_trust(ch) >= LEVEL_IMMORTAL)
+				write_to_descriptor(d,
+									"\n\rThe mud has been unresponsive for 60 seconds.  Rebooting.\n\r",
+									0);
 			write_to_descriptor(d, "\n\rThe mud has CRASHED.\007\n\r", 0);
 		}
 
@@ -2675,7 +2769,7 @@
 		if ((forkpid = fork()) > 0)
 		{
 			// Parent process copyover and exit 
-			waitpid(forkpid, NULL, WNOHANG | WUNTRACED);
+			waitpid(forkpid, &status, WNOHANG);
 			// this requires you to add an "if (ch)" before the chprint
 			// statements in do_copyover.
 			do_copyover(NULL, "");
@@ -2698,7 +2792,7 @@
 		default_action.sa_handler = SIG_DFL;
 		sigaction(sig, &default_action, NULL);
 
-		// I run different scripts depending on my port
+		// Run gdb script.
 		if (!fork())
 		{
 			execl(CORE_EXAMINE_SCRIPT, CORE_EXAMINE_SCRIPT, (char *) NULL);
@@ -2854,4 +2948,30 @@
 			mbr->level += mod;
 	}
 	save_members();
+}
+
+CH_CMD(do_crash)
+{
+	if (IS_NULLSTR(argument))
+	{
+		chprintln(ch, "Syntax: crash confirm - send a SIGSEGV to the mud.");
+		chprintln(ch, "      : crash loop    - start an infinite loop.");
+		return;
+	}
+
+	if (!str_cmp(argument, "loop"))
+	{
+		for (;;);
+		return;
+	}
+	else if (!str_cmp(argument, "confirm"))
+	{
+		raise(SIGSEGV);
+		return;
+	}
+	else
+	{
+		do_crash(ch, "");
+		return;
+	}
 }
diff -ur src/db.c new/db.c
--- src/db.c	Sun Apr 27 22:08:24 2003
+++ new/db.c	Thu May  8 14:57:41 2003
@@ -69,7 +69,7 @@
 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 !defined(NO_STRHASH)
+#if (STRHASH==1)
 char *string_hash[MAX_KEY_HASH];
 #endif
 
@@ -2678,7 +2678,7 @@
  */
 const char *fread_string(FILE * fp)
 {
-#if !defined(NO_STRHASH)
+#if (STRHASH==1)
 	char *plast;
 	char c;
 
@@ -2948,25 +2948,131 @@
 	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 *str)
+const char *str_dup(const char *pstr)
 {
 	char *str_new;
+#if (STRHASH==2)
+	int hash;
+	str *s;
+#endif
 
-	if (str[0] == '\0')
+	if (IS_NULLSTR(pstr))
 		return &str_empty[0];
 
-#if !defined(NO_STRHASH)
-	if (str >= string_space && str < top_string)
-		return str;
+#if (STRHASH==1)
+	if (pstr >= string_space && pstr < top_string)
+		return pstr;
 #endif
 
-	alloc_mem(str_new, char, strlen(str) + 1);
-	strcpy(str_new, str);
+#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);
+		return &str_empty[0];
+	}
+	strcpy(str_new, pstr);
 	return str_new;
+#endif
 }
 
 /*
@@ -2976,15 +3082,41 @@
  */
 void free_string(const char *pstr)
 {
+#if STRHASH==2
+	str *s, *q;
+	int hash;
+#endif
+
 	if (pstr == NULL || pstr == &str_empty[0]
-#if !defined(NO_STRHASH)
-		|| (pstr >= string_space && pstr < top_string))
-#else
-		)
+#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)
+		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
 	free_mem(pstr);
+#endif
 	return;
 }
 
@@ -3713,11 +3845,7 @@
  */
 void log_string(const char *str)
 {
-	char *strtime;
-
-	strtime = ctime(&current_time);
-	strtime[strlen(strtime) - 1] = '\0';
-	fprintf(stderr, "%s :: %s\n", strtime, str);
+	fprintf(stderr, "%s :: %s\n", str_time(current_time, -1, NULL), str);
 	return;
 }
 
diff -ur src/db.h new/db.h
--- src/db.h	Sun Apr 27 22:08:25 2003
+++ new/db.h	Thu May  8 14:57:42 2003
@@ -29,7 +29,7 @@
 #if !defined(DB_H)
 #define DB_H
 
-#if !defined(NO_STRHASH)
+#if (STRHASH==1)
 #define			MAX_STRING	    4000*1024
 #endif
 
diff -ur src/db2.c new/db2.c
--- src/db2.c	Sun Apr 27 22:08:24 2003
+++ new/db2.c	Thu May  8 14:57:41 2003
@@ -952,10 +952,12 @@
 CH_CMD(do_memory_heap)
 {
 	chprint(ch, separator);
-#if !defined(NO_STRHASH)
+#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);
@@ -1032,7 +1034,7 @@
 
 void strspace_alloc()
 {
-#if !defined(NO_STRHASH)
+#if (STRHASH==1)
 	extern char *top_string;
 
 	if ((string_space = (char *) calloc(1, MAX_STRING)) == NULL)
@@ -1084,6 +1086,52 @@
 		fpReserve = fopen(NULL_FILE, "r");
 
 	return TRUE;
+}
+
+FILE_DATA *fopen_temp(const char *file)
+{
+	FILE_DATA *fp;
+
+	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)
+	{
+		char temp[PATH_MAX];
+		snprintf(temp, PATH_MAX, "%s.tmp%d", file, number_percent());
+		strncpy(fp->tmp_name, temp, PATH_MAX);
+	}
+#else
+	strncpy(fp->tmp_name, file, PATH_MAX);
+#endif
+	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)
+		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[] = {
diff -ur src/dofun.h new/dofun.h
--- src/dofun.h	Sun Apr 27 22:08:25 2003
+++ new/dofun.h	Thu May  8 14:57:42 2003
@@ -324,5 +324,7 @@
 COMMAND_FUN (do_areaset)
 COMMAND_FUN (do_roster)
 COMMAND_FUN (do_map)
+COMMAND_FUN (do_timezone)
+COMMAND_FUN (do_crash)
 
 // *INDENT-ON*
diff -ur src/globals.h new/globals.h
--- src/globals.h	Sun Apr 27 22:08:25 2003
+++ new/globals.h	Thu May  8 14:57:42 2003
@@ -112,10 +112,13 @@
 GLOBAL_DEF(bool fBootDb, FALSE);
 GLOBAL_DEF(int newmobs, 0);
 GLOBAL_DEF(int newobjs, 0);
-#if !defined(NO_STRHASH)
+#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);
diff -ur src/gquest.c new/gquest.c
--- src/gquest.c	Sun Apr 27 22:08:24 2003
+++ new/gquest.c	Thu May  8 14:57:41 2003
@@ -237,7 +237,6 @@
 	MOB_INDEX_DATA *mob;
 	int i;
 	GQUEST_HIST *hist;
-	char *strtime;
 	char shortd[MAX_INPUT_LENGTH];
 	char buf[MAX_STRING_LENGTH];
 
@@ -245,11 +244,9 @@
 		return;
 
 	alloc_mem(hist, GQUEST_HIST, 1);
-	strtime = ctime(&current_time);
-	strtime[strlen(strtime) - 1] = '\0';
-	sprintf(shortd, "%24s %3d %3d %4d %12s\n\r", strtime,
-			gquest_info.minlevel, gquest_info.maxlevel,
-			gquest_info.mob_count, ch->name);
+	sprintf(shortd, "%24s %3d %3d %4d %12s\n\r",
+			str_time(current_time, -1, NULL), gquest_info.minlevel,
+			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");
@@ -263,7 +260,7 @@
 	sprintf(buf, "Those Playing\n\r-------------\n\r");
 	add_buf(output, buf);
 	for (wch = char_first; wch != NULL; wch = wch->next)
-		if (!IS_NPC(ch) && ON_GQUEST(wch)
+		if (!IS_NPC(wch) && ON_GQUEST(wch)
 			&& count_gqmobs(wch) != gquest_info.mob_count)
 			sprintf(buf, "%s [%d mobs left]\n\r", wch->name,
 					gquest_info.mob_count - count_gqmobs(wch));
diff -ur src/handler.c new/handler.c
--- src/handler.c	Sun Apr 27 22:08:24 2003
+++ new/handler.c	Thu May  8 14:57:41 2003
@@ -2646,3 +2646,29 @@
 	}
 	return ch;
 }
+
+char *str_time(time_t timet, int tz, const char *format)
+{
+	static char buf_new[5][100];
+	static int i;
+	char *result;
+
+	// rotate buffers
+	++i;
+	i %= 5;
+	result = buf_new[i];
+
+	if (timet <= 0)
+	{
+		timet = current_time;
+	}
+	if (tz > -1 && tz < MAX_TZONE)
+	{
+		timet += timezone;
+		timet += (60 * 60 * tzone_table[tz].gmt_offset);
+	}
+	strftime(result, 100, !IS_NULLSTR(format) ? format : "%a %b %d %r %Y",
+			 localtime(&timet));
+
+	return result;
+}
diff -ur src/interp.c new/interp.c
--- src/interp.c	Sun Apr 27 22:08:24 2003
+++ new/interp.c	Thu May  8 14:57:42 2003
@@ -661,7 +661,7 @@
 /* Save disabled commands */
 void save_disabled()
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	DISABLED_DATA *p;
 
 	if (!disabled_first)		/* delete file if no commands are disabled */
@@ -670,7 +670,7 @@
 		return;
 	}
 
-	fp = file_open(DISABLED_FILE, "w");
+	fp = fopen_temp(DISABLED_FILE);
 
 	if (!fp)
 	{
@@ -679,9 +679,10 @@
 	}
 
 	for (p = disabled_first; p; p = p->next)
-		fprintf(fp, "%s %d %s\n", p->command->name, p->level, p->disabled_by);
+		fprintf(fp->file, "%s %d %s\n", p->command->name, p->level,
+				p->disabled_by);
 
-	fprintf(fp, "%s\n", END_MARKER);
+	fprintf(fp->file, "%s\n", END_MARKER);
 
-	file_close(fp);
+	fclose_temp(fp);
 }
diff -ur src/interp.h new/interp.h
--- src/interp.h	Sun Apr 27 22:08:25 2003
+++ new/interp.h	Thu May  8 14:57:42 2003
@@ -101,5 +101,6 @@
 DECLARE_DO_FUN(do_mset);
 DECLARE_DO_FUN(do_oset);
 DECLARE_DO_FUN(do_slookup);
+DECLARE_DO_FUN(do_ncheck);
 
 #endif
diff -ur src/lookup.c new/lookup.c
--- src/lookup.c	Sun Apr 27 22:08:24 2003
+++ new/lookup.c	Thu May  8 14:57:42 2003
@@ -198,3 +198,20 @@
 
 	return NULL;
 }
+
+int tzone_lookup(const char *arg)
+{
+	int i;
+
+	for (i = 0; i < MAX_TZONE; i++)
+	{
+		if (!str_cmp(arg, tzone_table[i].name))
+			return i;
+	}
+	for (i = 0; i < MAX_TZONE; i++)
+	{
+		if (is_name(arg, tzone_table[i].zone))
+			return i;
+	}
+	return -1;
+}
diff -ur src/lookup.h new/lookup.h
--- src/lookup.h	Sun Apr 27 22:08:25 2003
+++ new/lookup.h	Thu May  8 14:57:42 2003
@@ -35,5 +35,6 @@
 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));
 
 #endif
diff -ur src/merc.h new/merc.h
--- src/merc.h	Sun Apr 27 22:08:25 2003
+++ new/merc.h	Thu May  8 14:57:42 2003
@@ -148,6 +148,7 @@
 typedef struct deity_type DEITY_DATA;
 typedef struct wpwd_data WPWD_DATA;
 typedef struct mbr_data MBR_DATA;
+typedef struct file_data FILE_DATA;
 
 /*
  * Function types.
@@ -182,6 +183,7 @@
  * 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
@@ -369,19 +371,20 @@
 #define CON_GET_NEW_CLASS		 8
 #define CON_GET_ALIGNMENT		 9
 #define CON_GET_DEITY           10
-#define CON_DEFAULT_CHOICE		11
-#define CON_GEN_GROUPS			12
-#define CON_PICK_WEAPON			13
-#define CON_READ_IMOTD			14
-#define CON_READ_MOTD			15
-#define CON_BREAK_CONNECT		16
-#define CON_GET_TERM	        17
-#define CON_COPYOVER_RECOVER    18
-#define CON_NOTE_TO				19
-#define CON_NOTE_SUBJECT		20
-#define CON_NOTE_EXPIRE			21
-#define CON_NOTE_TEXT			22
-#define CON_NOTE_FINISH			23
+#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.
@@ -1455,13 +1458,24 @@
 #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,
+	MAX_WAR = 6
+};
+
 struct war_data
 {
 	const char *who;
 	int min_level;
 	int max_level;
 	int inwar;
-	int wartype;
+	enum war_types wartype;
 	int timer;
 	int iswar;
 	int next;
@@ -1741,7 +1755,7 @@
 	const char *alias[MAX_ALIAS];
 	const char *alias_sub[MAX_ALIAS];
 	int security;				/* OLC *//* Builder security */
-	int colour[MAX_CUSTOM_COLOUR];
+	int colour[MAX_CUSTOM_COLOUR][3];
 	long gamestat[MAX_GAMESTAT];
 	int nextquest;
 	int countdown;
@@ -1769,6 +1783,7 @@
 	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 */
@@ -2092,6 +2107,19 @@
 	PROG_CODE *prev;
 };
 
+#if defined(WIN32)
+#define PATH_MAX MAX_PATH
+#else
+#include <limits.h>
+#endif
+
+struct file_data
+{
+	FILE *file;
+	char tmp_name[PATH_MAX];
+	char name[PATH_MAX];
+};
+
 #include "gsn.h"
 
 /*
@@ -2356,6 +2384,8 @@
 #define	ON_GQUEST(ch)      (!IS_NPC(ch) && IS_SET((ch)->act, PLR_GQUEST) && gquest_info.running != GQUEST_OFF)
 
 #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.
diff -ur src/nanny.c new/nanny.c
--- src/nanny.c	Sun Apr 27 22:08:24 2003
+++ new/nanny.c	Thu May  8 14:57:42 2003
@@ -37,6 +37,7 @@
 #include "telnet.h"
 #include "recycle.h"
 #include "lookup.h"
+#include "tables.h"
 
 bool check_playing args((DESCRIPTOR_DATA * d, const char *name));
 bool check_parse_name args((const char *name));
@@ -61,10 +62,11 @@
 	case 't':
 	case 'T':
 		write_to_buffer(d,
-						"\n\rThis text should be " CB_GREEN
-						"GREEN" C_CLEAR
-						".\n\rThis text should be " CB_RED "RED"
-						C_CLEAR ".\n\r", 0);
+						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);
 		return;
 	default:
@@ -555,6 +557,21 @@
 	return;
 }
 
+void send_timezone_info(DESCRIPTOR_DATA * d)
+{
+	int i;
+	CHAR_DATA *ch = CH(d);
+
+	chprintlnf(ch, "%-6s %-29s (%s)", "Name", "City/Zone Crosses", "Time");
+	chprintlnf(ch, "%s", draw_line(ch, NULL, 0));
+	for (i = 0; i < MAX_TZONE; i++)
+	{
+		chprintlnf(ch, "%-6s %-29s (%s)", tzone_table[i].name,
+				   tzone_table[i].zone, str_time(current_time, i, NULL));
+	}
+	chprintlnf(ch, "%s", draw_line(ch, NULL, 0));
+}
+
 void handle_con_get_deity(DESCRIPTOR_DATA * d, const char *argument)
 {
 	char arg[MIL];
@@ -588,6 +605,53 @@
 	ch->deity = i;
 	sprintf(buf, "\n\rYou now worship %s.\n\r", ch->deity->name);
 	write_to_buffer(d, buf, 0);
+
+	send_timezone_info(d);
+	write_to_buffer(d, "What time zone do you live in?\n\r", 0);
+	d->connected = CON_GET_TIMEZONE;
+	return;
+}
+
+void handle_con_get_timezone(DESCRIPTOR_DATA * d, const char *argument)
+{
+	int i;
+	char arg[MIL];
+	char buf[MSL];
+	CHAR_DATA *ch = CH(d);
+
+	one_argument(argument, arg);
+
+	if (IS_NULLSTR(arg))
+	{
+		send_timezone_info(d);
+		write_to_buffer(d, "What time zone do you live in?\n\r", 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);
+		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);
+		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);
 
 	group_add(ch, "rom basics", FALSE);
@@ -830,7 +894,7 @@
 		act("$n has entered the game.", ch->pet, NULL, NULL, TO_ROOM);
 	}
 
-	do_function(ch, &do_board, "");
+	do_function(ch, &do_ncheck, "");
 	unfinished_quest(ch);
 	update_explored(ch);
 	checkcorpse(ch);
@@ -905,6 +969,10 @@
 
 	case CON_GET_DEITY:
 		handle_con_get_deity(d, argument);
+		break;
+
+	case CON_GET_TIMEZONE:
+		handle_con_get_timezone(d, argument);
 		break;
 
 	case CON_DEFAULT_CHOICE:
diff -ur src/olc.c new/olc.c
--- src/olc.c	Sun Apr 27 22:08:25 2003
+++ new/olc.c	Thu May  8 14:57:42 2003
@@ -759,7 +759,7 @@
 	{"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", (void *) &xRace.name, olced_str, NULL},
+	{"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},
diff -ur src/olc.h new/olc.h
--- src/olc.h	Sun Apr 27 22:08:25 2003
+++ new/olc.h	Thu May  8 14:57:42 2003
@@ -354,6 +354,7 @@
 DECLARE_OLC_FUN(raedit_mstats);
 DECLARE_OLC_FUN(raedit_skills);
 DECLARE_OLC_FUN(raedit_classx);
+DECLARE_OLC_FUN(raedit_name);
 
 DECLARE_OLC_FUN(cledit_create);
 DECLARE_OLC_FUN(cledit_delete);
diff -ur src/olc_group.c new/olc_group.c
--- src/olc_group.c	Sun Apr 27 22:08:25 2003
+++ new/olc_group.c	Thu May  8 14:57:42 2003
@@ -68,6 +68,7 @@
 	GROUP_DATA *pGroup;
 	struct group_type *new_table;
 	char buf[MIL];
+	CHAR_DATA *pch;
 
 	if (!IS_NULLSTR(argument) && group_lookup(argument) == -1)
 		sprintf(buf, argument);
@@ -97,6 +98,12 @@
 
 	alloc_mem(group_table[i].rating, int, maxClass);
 
+	for (pch = player_first; pch; pch = pch->next_player)
+	{
+		realloc_mem(pch->pcdata->group_known, bool, maxGroup);
+		if (pch->gen_data != NULL)
+			realloc_mem(pch->gen_data->group_chosen, bool, maxGroup);
+	}
 	pGroup = &group_table[i];
 	chprintln(ch, "Group created.");
 	edit_start(ch, pGroup, ED_GROUP);
diff -ur src/olc_race.c new/olc_race.c
--- src/olc_race.c	Sun Apr 27 22:08:25 2003
+++ new/olc_race.c	Thu May  8 14:57:42 2003
@@ -421,3 +421,42 @@
 
 	return TRUE;
 }
+
+RAEDIT(raedit_name)
+{
+	RACE_DATA *pRace;
+	MOB_INDEX_DATA *pMob;
+	int ihash;
+	char arg[MIL];
+
+	EDIT_RACE(ch, pRace);
+
+	first_arg(argument, arg, FALSE);
+
+	if (IS_NULLSTR(arg))
+	{
+		chprintln(ch, "Change name to what?");
+		return FALSE;
+	}
+
+	if (race_lookup(arg) != NULL)
+	{
+		chprintln(ch, "A race with that name already exists.");
+		return FALSE;
+	}
+
+	if (str_cmp(arg, pRace->name))
+	{
+		for (ihash = 0; ihash < MAX_KEY_HASH; ihash++)
+		{
+			for (pMob = mob_index_hash[ihash]; pMob; pMob = pMob->next)
+			{
+				if (pMob->race == pRace)
+					SET_BIT(pMob->area->area_flags, AREA_CHANGED);
+			}
+		}
+	}
+	replace_string(pRace->name, arg);
+	chprintln(ch, "Name set.");
+	return TRUE;
+}
diff -ur src/olc_save.c new/olc_save.c
--- src/olc_save.c	Sun Apr 27 22:08:25 2003
+++ new/olc_save.c	Thu May  8 14:57:42 2003
@@ -97,33 +97,25 @@
  ****************************************************************************/
 void save_area_list()
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	AREA_DATA *pArea;
-#if !defined(WIN32)
-	char *TEMPFILE = "area.lst.tmp";
-#else
-	char *TEMPFILE = "area.lst";
-#endif
 
-	if ((fp = file_open(TEMPFILE, "w")) == NULL)
+	if ((fp = fopen_temp("area.lst")) == NULL)
 	{
 		bug("Save_area_list: file_open", 0);
 		perror("area.lst");
 	}
 	else
 	{
-		fprintf(fp, "%s\n", HELP_FILE);
+		fprintf(fp->file, "%s\n", HELP_FILE);
 
 		for (pArea = area_first; pArea; pArea = pArea->next)
 		{
-			fprintf(fp, "%s\n", pArea->file_name);
+			fprintf(fp->file, "%s\n", pArea->file_name);
 		}
 
-		fprintf(fp, "$\n");
-		file_close(fp);
-#if !defined(WIN32)
-		rename(TEMPFILE, "area.lst");
-#endif
+		fprintf(fp->file, "$\n");
+		fclose_temp(fp);
 	}
 
 	return;
@@ -936,32 +928,24 @@
 void save_helps(void)
 {
 	HELP_DATA *help;
-	FILE *fp;
-#if !defined(WIN32)
-	char *TEMPFILE = HELP_FILE ".tmp";
+	FILE_DATA *fp;
 
-	if ((fp = file_open(TEMPFILE, "w")) != NULL)
-#else
-	if ((fp = file_open(HELP_FILE, "w")) != NULL)
-#endif
+	if ((fp = fopen_temp(HELP_FILE)) != NULL)
 	{
-		fprintf(fp, "#HELPS\n");
+		fprintf(fp->file, "#HELPS\n");
 
 		for (help = help_first; help; help = help->next)
 		{
-			fprintf(fp, "%d %s~\n", help->level, help->keyword);
-			fprintf(fp, "%s~\n\n", fix_string(help->text));
+			fprintf(fp->file, "%d %s~\n", help->level, help->keyword);
+			fprintf(fp->file, "%s~\n\n", fix_string(help->text));
 		}
 
-		fprintf(fp, "-1 $~\n\n");
-		fprintf(fp, "#$\n");
+		fprintf(fp->file, "-1 $~\n\n");
+		fprintf(fp->file, "#$\n");
+		fclose_temp(fp);
 	}
 	else
 		bug("Error opening " HELP_FILE ".", 0);
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, HELP_FILE);
-#endif
 	return;
 }
 
@@ -972,16 +956,9 @@
  ****************************************************************************/
 void save_area(AREA_DATA * pArea)
 {
-	FILE *fp;
-	char TEMPFILE[MIL];
+	FILE_DATA *fp;
 
-#if defined(WIN32)
-	strcpy(TEMPFILE, pArea->file_name);
-#else
-	sprintf(TEMPFILE, "%s.tmp", pArea->file_name);
-#endif
-
-	if (!(fp = file_open(TEMPFILE, "w")))
+	if (!(fp = fopen_temp(pArea->file_name)))
 	{
 		bug("Open_area: file_open", 0);
 		perror(pArea->file_name);
@@ -989,36 +966,33 @@
 	else
 	{
 		REMOVE_BIT(pArea->area_flags, AREA_CHANGED);
-		fprintf(fp, "#AREADATA\n");
-		fprintf(fp, "Name %s~\n", pArea->name);
-		fprintf(fp, "Builders %s~\n", fix_string(pArea->builders));
-		fprintf(fp, "VNUMs %ld %ld\n", pArea->min_vnum, pArea->max_vnum);
-		fprintf(fp, "Credits %s~\n", pArea->credits);
+		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, "LvlComment %s~\n", pArea->lvl_comment);
-		fprintf(fp, "MinLevel %d\n", pArea->min_level);
-		fprintf(fp, "MaxLevel %d\n", pArea->max_level);
-		fprintf(fp, "Version %d\n", AREA_VERSION);
-		fprintf(fp, "Security %d\n", pArea->security);
-		fprintf(fp, "Flags %s\n", fwrite_flags(pArea->area_flags));
-		fprintf(fp, "End\n\n\n\n");
-
-		save_mobiles(fp, pArea);
-		save_objects(fp, pArea);
-		save_rooms(fp, pArea);
-		save_specials(fp, pArea);
-		save_resets(fp, pArea);
-		save_shops(fp, pArea);
-		save_mobprogs(fp, pArea);
-		save_objprogs(fp, pArea);
-		save_roomprogs(fp, pArea);
-
-		fprintf(fp, "#$\n");
-
-		file_close(fp);
-#if !defined(WIN32)
-		rename(TEMPFILE, pArea->file_name);
-#endif
+			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->file, "#$\n");
+
+		fclose_temp(fp);
 	}
 	return;
 }
diff -ur src/olc_skill.c new/olc_skill.c
--- src/olc_skill.c	Sun Apr 27 22:08:25 2003
+++ new/olc_skill.c	Thu May  8 14:57:42 2003
@@ -145,6 +145,7 @@
 	SKILL_DATA *pSkill;
 	struct skill_type *new_table;
 	char buf[MIL];
+	CHAR_DATA *pch;
 
 	if (!IS_NULLSTR(argument) && skill_lookup(argument) == -1)
 		sprintf(buf, argument);
@@ -181,6 +182,12 @@
 	alloc_mem(skill_table[i].skill_level, int, maxClass);
 	alloc_mem(skill_table[i].rating, int, maxClass);
 
+	for (pch = player_first; pch; pch = pch->next_player)
+	{
+		realloc_mem(pch->pcdata->learned, int, maxSkill);
+		if (pch->gen_data != NULL)
+			realloc_mem(pch->gen_data->skill_chosen, bool, maxSkill);
+	}
 	pSkill = &skill_table[i];
 	edit_start(ch, pSkill, ED_SKILL);
 	chprintln(ch, "Skill created.");
diff -ur src/proto.h new/proto.h
--- src/proto.h	Sun Apr 27 22:08:25 2003
+++ new/proto.h	Thu May  8 14:57:42 2003
@@ -161,7 +161,7 @@
 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 *str));
+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));
@@ -194,6 +194,8 @@
 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));
 
 /* effect.c */
 void acid_effect args((void *vo, int level, int dam, int target));
@@ -591,6 +593,11 @@
 	  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));
 
 #undef	CD
 #undef	MID
diff -ur src/save.c new/save.c
--- src/save.c	Sun Apr 27 22:08:25 2003
+++ new/save.c	Thu May  8 14:57:42 2003
@@ -118,14 +118,14 @@
 {
 	AFFECT_DATA *paf;
 	int sn, gn, pos;
-	int i;
+	int i, j;
 
 	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", 7);
+	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')
@@ -255,7 +255,9 @@
 			fprintf(fp, "Trivia  %d\n", ch->pcdata->trivia);
 
 		if (ch->pcdata->str_ed_key != '.' && ch->pcdata->str_ed_key != ' ')
-			fprintf(fp, "StrEdKey\t%c\n", 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);
@@ -295,7 +297,8 @@
 
 		fprintf(fp, "Colo  %d ", MAX_CUSTOM_COLOUR);
 		for (i = 0; i < MAX_CUSTOM_COLOUR; i++)
-			fprintf(fp, "%d ", ch->pcdata->colour[i]);
+			for (j = 0; j < 3; j++)
+				fprintf(fp, "%d ", ch->pcdata->colour[i][j]);
 		fprintf(fp, "\n");
 
 		if (ch->pcdata->who_descr[0] != '\0')
@@ -621,6 +624,7 @@
 	ch->pcdata->trivia = 0;
 	end_quest(ch, 0);
 	reset_gqmob(ch, 0);
+	ch->pcdata->timezone = -1;
 }
 
 /*
@@ -1028,13 +1032,17 @@
 			KEY("Comm", ch->comm, fread_flag(fp));
 			if (!str_cmp(word, "Colo"))
 			{
-				int i, num = fread_number(fp);
-
-				for (i = 0; i < num; i++)
+				if (ch->version >= 8)
 				{
-					ch->pcdata->colour[i] = fread_number(fp);
-					if (i >= MAX_CUSTOM_COLOUR)
-						break;
+					int i, j, num = fread_number(fp);
+
+					for (i = 0; i < num; i++)
+					{
+						for (j = 0; j < 3; j++)
+							ch->pcdata->colour[i][j] = fread_number(fp);
+						if (i >= MAX_CUSTOM_COLOUR)
+							break;
+					}
 				}
 				fread_to_eol(fp);
 				fMatch = TRUE;
@@ -1288,6 +1296,7 @@
 			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));
 			if (!str_cmp(word, "Title") || !str_cmp(word, "Titl"))
 			{
 				ch->pcdata->title = fread_string(fp);
@@ -1920,15 +1929,10 @@
 
 void save_corpses(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	CORPSE_DATA *c;
-#if !defined(WIN32)
-	char *TEMPFILE = CORPSE_FILE ".tmp";
 
-	if ((fp = file_open(TEMPFILE, "w")) == NULL)
-#else
-	if ((fp = file_open(CORPSE_FILE, "w")) == NULL)
-#endif
+	if ((fp = fopen_temp(CORPSE_FILE)) == NULL)
 	{
 		bug("save_corpses: " CORPSE_FILE " not found.", 0);
 	}
@@ -1937,17 +1941,14 @@
 		for (c = corpse_first; c != NULL; c = c->next)
 		{
 			if (c->corpse->item_type == ITEM_CORPSE_PC)
-				fwrite_obj(NULL, c->corpse, fp, 0, "C");
+				fwrite_obj(NULL, c->corpse, fp->file, 0, "C");
 			else
 				update_corpses(c->corpse, TRUE);
 		}
-		fprintf(fp, "#END\n");
-		fflush(fp);
+		fprintf(fp->file, "#END\n");
+		fflush(fp->file);
+		fclose_temp(fp);
 	}
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, CORPSE_FILE);
-#endif
 	return;
 }
 
diff -ur src/string.c new/string.c
--- src/string.c	Sun Apr 27 22:08:25 2003
+++ new/string.c	Thu May  8 14:57:42 2003
@@ -947,11 +947,18 @@
 			str++;
 			if (*str == '-')
 			{
-				buf[i] = C_TILDE;
+				buf[i] = '~';
 				i++;
 			}
 			str++;
 		}
+		else if (*str == ANSI_CUSTOM)
+		{
+			str++;
+			while (*str != ANSI_END)
+				str++;
+			str++;
+		}
 		else
 		{
 			buf[i] = *str;
@@ -1050,6 +1057,13 @@
 				nCount++;
 			continue;
 		}
+		else if (temp == ANSI_CUSTOM)
+		{
+			temp = *count_string++;
+			while (temp != ANSI_END)
+				temp = *count_string++;
+			continue;
+		}
 		nCount++;
 	}
 
@@ -1087,6 +1101,14 @@
 			pos++;
 			continue;
 		}
+		else if (temp == ANSI_CUSTOM)
+		{
+			temp = result[pos++] = *string++;
+
+			while (temp != ANSI_END)
+				temp = result[pos++] = *string++;
+			continue;
+		}
 		count++;
 	}
 
@@ -1106,7 +1128,7 @@
 
 	while (*string != '\0')
 	{
-		if (*string != ANSI_KEY)
+		if (*string != ANSI_KEY && *string != ANSI_CUSTOM)
 		{
 			count++;
 			string++;
@@ -1125,7 +1147,16 @@
 			string++;
 			continue;
 		}
-		else if (*string == ANSI_KEY && *(string + 1) == '\0')
+		else if (*string == ANSI_CUSTOM && *(string + 1) != '\0')
+		{
+			string++;
+			while (*string != '\0' && *string != ANSI_END)
+				string++;
+			string++;
+			continue;
+		}
+		else if ((*string == ANSI_KEY || *string == ANSI_CUSTOM)
+				 && *(string + 1) == '\0')
 		{
 			break;
 		}
@@ -1235,6 +1266,19 @@
 				count++;
 			if (count >= mod)
 				break;
+			continue;
+		}
+		else if (fill[m] == ANSI_CUSTOM)
+		{
+			lbuf[m] = fill[m];
+			m++;
+			while (fill[m] != ANSI_END)
+			{
+				lbuf[m] = fill[m];
+				m++;
+			}
+			lbuf[m] = fill[m];
+			m++;
 			continue;
 		}
 		else
diff -ur src/tables.c new/tables.c
--- src/tables.c	Sun Apr 27 22:08:25 2003
+++ new/tables.c	Thu May  8 14:57:42 2003
@@ -772,96 +772,95 @@
 	{weapon_type2, "weapon"}
 };
 
-const struct colour_type colour_chars[] = {
-	{"Reset", C_CLEAR},
-	{"Black", C_BLACK},
-	{"Red", C_RED},
-	{"Green", C_GREEN},
-	{"Yellow", C_YELLOW},
-	{"Blue", C_BLUE},
-	{"Magenta", C_MAGENTA},
-	{"Cyan", C_CYAN},
-	{"White", C_WHITE},
-	{"B_Black", CB_BLACK},
-	{"B_Red", CB_RED},
-	{"B_Green", CB_GREEN},
-	{"B_Yellow", CB_YELLOW},
-	{"B_Blue", CB_BLUE},
-	{"B_Magenta", CB_MAGENTA},
-	{"B_Cyan", CB_CYAN},
-	{"B_White", CB_WHITE},
-	{"Random", C_RANDOM},
-	{"RedBG", RED_BG},
-	{"BlueBG", BLUE_BG},
-	{"GreenBG", GREEN_BG},
-	{"BlackBG", BLACK_BG},
-	{"WhiteBG", WHITE_BG},
-	{"MagentaBG", MAGENTA_BG},
-	{"YellowBG", YELLOW_BG},
-	{"CyanBG", CYAN_BG},
-	{"B_RedBG", RED_BBG},
-	{"B_BlueBG", BLUE_BBG},
-	{"B_GreenBG", GREEN_BBG},
-	{"B_BlackBG", BLACK_BBG},
-	{"B_WhiteBG", WHITE_BBG},
-	{"B_MagentaBG", MAGENTA_BBG},
-	{"B_YellowBG", YELLOW_BBG},
-	{"B_CyanBG", CYAN_BBG},
-	{"RandomBG", RANDOM_BG},
-	{NULL, C_FLASH},
-	{NULL, C_UNDERSCORE},
-	{NULL, C_REVERSE},
-	{NULL, NULL}
-};
-
-const struct cslot_type cslot_table[] = {
-
-	{"Clear", _DEFAULT, C_CLEAR},
-	{"Gossip1", _GOSSIP1, C_MAGENTA},
-	{"Gossip2", _GOSSIP2, CB_MAGENTA},
-	{"Gossip3", _GOSSIP3, CB_GREEN},
-	{"Music1", _MUSIC1, C_RED},
-	{"Music2", _MUSIC2, CB_RED},
-	{"Music3", _MUSIC3, CB_WHITE},
-	{"Q/A1", _QA1, CB_YELLOW},
-	{"Q/A2", _QA2, C_YELLOW},
-	{"Q/A3", _QA3, C_CLEAR},
-	{"Quote1", _QUOTE1, CB_GREEN},
-	{"Quote2", _QUOTE2, CB_WHITE},
-	{"Quote3", _QUOTE3, CB_RED},
-	{"Gratz1", _GRATS1, CB_YELLOW},
-	{"Gratz2", _GRATS2, C_GREEN},
-	{"Gratz3", _GRATS3, CB_WHITE},
-	{"Shout1", _SHOUT1, C_WHITE},
-	{"Shout2", _SHOUT2, C_MAGENTA},
-	{"ImmTalk1", _IMMTALK1, C_YELLOW},
-	{"ImmTalk2", _IMMTALK2, C_CYAN},
-	{"ImmTalk3", _IMMTALK3, C_CYAN},
-	{"Tells1", _TELLS1, C_CYAN},
-	{"Tells2", _TELLS2, CB_CYAN},
-	{"Say1", _SAY1, C_GREEN},
-	{"Say2", _SAY2, CB_GREEN},
-	{"Skill", _SKILL, CB_YELLOW},
-	{"YHit", _YHIT, C_GREEN},
-	{"OHit", _OHIT, C_BLUE},
-	{"VHit", _VHIT, C_RED},
-	{"WhoRace", _WRACE, CB_RED},
-	{"WhoClass", _WCLASS, CB_CYAN},
-	{"WhoLevel", _WLEVEL, CB_BLUE},
-	{"RoomTitle", _RTITLE, CB_GREEN},
-	{"Score1", _SCORE1, C_CYAN},
-	{"Score2", _SCORE2, CB_CYAN},
-	{"Score3", _SCORE3, CB_WHITE},
-	{"Score4", _SCOREB, C_CLEAR},
-	{"Wiznet", _WIZNET, C_GREEN},
-	{"Gtell1", _GTELL1, CB_BLUE},
-	{"Gtell2", _GTELL2, CB_MAGENTA},
-	{"Whois1", _WHOIS1, C_GREEN},
-	{"Whois2", _WHOIS2, CB_WHITE},
-	{"Whois3", _WHOISB, C_CYAN},
-	{"Btalk1", _BTALK1, CB_BLUE},
-	{"Btalk2", _BTALK2, CB_WHITE},
-	{NULL, -1, NULL}
+const struct colour_type colour_attributes[] = {
+	{"default", CL_CLEAR},
+	{"bright", CL_BRIGHT},
+	{"dim", CL_DIM},
+	{"standout", CL_STANDOUT},
+	{"underscore", CL_UNDER},
+	{"blink", CL_BLINK},
+	{"italic", CL_ITALIC},
+	{"reverse", CL_REVERSE},
+	{"hidden", CL_REVERSE},
+	{"random", CL_RANDOM},
+	{NULL, 0}
+};
+
+const struct colour_type colour_foregrounds[] = {
+	{"black", FG_BLACK},
+	{"red", FG_RED},
+	{"green", FG_GREEN},
+	{"yellow", FG_YELLOW},
+	{"blue", FG_BLUE},
+	{"magenta", FG_MAGENTA},
+	{"cyan", FG_CYAN},
+	{"white", FG_WHITE},
+	{"random", FG_RANDOM},
+	{"none", FG_NONE},
+	{NULL, 0}
+};
+
+const struct colour_type colour_backgrounds[] = {
+	{"black", BG_BLACK},
+	{"red", BG_RED},
+	{"green", BG_GREEN},
+	{"yellow", BG_YELLOW},
+	{"blue", BG_BLUE},
+	{"magenta", BG_MAGENTA},
+	{"cyan", BG_CYAN},
+	{"white", BG_WHITE},
+	{"random", BG_RANDOM},
+	{"none", BG_NONE},
+	{NULL, 0}
+};
+
+const struct cslot_type cslot_table[MAX_CUSTOM_COLOUR] = {
+
+	{"Clear", _DEFAULT, CL_CLEAR, FG_NONE, BG_NONE},
+	{"Gossip1", _GOSSIP1, CL_CLEAR, FG_MAGENTA, BG_NONE},
+	{"Gossip2", _GOSSIP2, CL_BRIGHT, FG_MAGENTA, BG_NONE},
+	{"Gossip3", _GOSSIP3, CL_BRIGHT, FG_GREEN, BG_NONE},
+	{"Music1", _MUSIC1, CL_CLEAR, FG_RED, BG_NONE},
+	{"Music2", _MUSIC2, CL_BRIGHT, FG_RED, BG_NONE},
+	{"Music3", _MUSIC3, CL_BRIGHT, FG_WHITE, BG_NONE},
+	{"Q/A1", _QA1, CL_BRIGHT, FG_YELLOW, BG_NONE},
+	{"Q/A2", _QA2, CL_CLEAR, FG_YELLOW, BG_NONE},
+	{"Q/A3", _QA3, CL_CLEAR, FG_NONE, BG_NONE},
+	{"Quote1", _QUOTE1, CL_BRIGHT, FG_GREEN, BG_NONE},
+	{"Quote2", _QUOTE2, CL_BRIGHT, FG_WHITE, BG_NONE},
+	{"Quote3", _QUOTE3, CL_BRIGHT, FG_RED, BG_NONE},
+	{"Gratz1", _GRATS1, CL_BRIGHT, FG_YELLOW, BG_NONE},
+	{"Gratz2", _GRATS2, CL_CLEAR, FG_GREEN, BG_NONE},
+	{"Gratz3", _GRATS3, CL_BRIGHT, FG_WHITE, BG_NONE},
+	{"Shout1", _SHOUT1, CL_CLEAR, FG_WHITE, BG_NONE},
+	{"Shout2", _SHOUT2, CL_CLEAR, FG_MAGENTA, BG_NONE},
+	{"ImmTalk1", _IMMTALK1, CL_CLEAR, FG_YELLOW, BG_NONE},
+	{"ImmTalk2", _IMMTALK2, CL_CLEAR, FG_CYAN, BG_NONE},
+	{"ImmTalk3", _IMMTALK3, CL_CLEAR, FG_CYAN, BG_NONE},
+	{"Tells1", _TELLS1, CL_CLEAR, FG_CYAN, BG_NONE},
+	{"Tells2", _TELLS2, CL_BRIGHT, FG_CYAN, BG_NONE},
+	{"Say1", _SAY1, CL_CLEAR, FG_GREEN, BG_NONE},
+	{"Say2", _SAY2, CL_BRIGHT, FG_GREEN, BG_NONE},
+	{"Skill", _SKILL, CL_BRIGHT, FG_YELLOW, BG_NONE},
+	{"YHit", _YHIT, CL_CLEAR, FG_GREEN, BG_NONE},
+	{"OHit", _OHIT, CL_CLEAR, FG_BLUE, BG_NONE},
+	{"VHit", _VHIT, CL_CLEAR, FG_RED, BG_NONE},
+	{"WhoRace", _WRACE, CL_BRIGHT, FG_RED, BG_NONE},
+	{"WhoClass", _WCLASS, CL_BRIGHT, FG_CYAN, BG_NONE},
+	{"WhoLevel", _WLEVEL, CL_BRIGHT, FG_BLUE, BG_NONE},
+	{"RoomTitle", _RTITLE, CL_BRIGHT, FG_GREEN, BG_NONE},
+	{"Score1", _SCORE1, CL_CLEAR, FG_CYAN, BG_NONE},
+	{"Score2", _SCORE2, CL_BRIGHT, FG_CYAN, BG_NONE},
+	{"Score3", _SCORE3, CL_BRIGHT, FG_WHITE, BG_NONE},
+	{"Score4", _SCOREB, CL_CLEAR, FG_NONE, BG_NONE},
+	{"Wiznet", _WIZNET, CL_CLEAR, FG_GREEN, BG_NONE},
+	{"Gtell1", _GTELL1, CL_BRIGHT, FG_BLUE, BG_NONE},
+	{"Gtell2", _GTELL2, CL_BRIGHT, FG_MAGENTA, BG_NONE},
+	{"Whois1", _WHOIS1, CL_CLEAR, FG_GREEN, BG_NONE},
+	{"Whois2", _WHOIS2, CL_BRIGHT, FG_WHITE, BG_NONE},
+	{"Whois3", _WHOISB, CL_CLEAR, FG_CYAN, BG_NONE},
+	{"Btalk1", _BTALK1, CL_BRIGHT, FG_BLUE, BG_NONE},
+	{"Btalk2", _BTALK2, CL_BRIGHT, FG_WHITE, BG_NONE}
 };
 
 const struct vnum_type vnum_table[] = {
@@ -968,4 +967,32 @@
 	{"obj_char_defensive", TAR_OBJ_CHAR_DEF, TRUE},
 	{"obj_char_offensive", TAR_OBJ_CHAR_OFF, TRUE},
 	{NULL, 0, 0}
+};
+
+const struct tzone_type tzone_table[MAX_TZONE] = {
+	{"GMT-12", "Eniwetok", -12, 0},
+	{"GMT-11", "Samoa", -11, 0},
+	{"GMT-10", "Hawaii", -10, 0},
+	{"GMT-9", "Alaska", -9, 0},
+	{"GMT-8", "PST, Pacific US", -8, -7},
+	{"GMT-7", "MST, Mountain US", -7, -6},
+	{"GMT-6", "CST, Central US", -6, -5},
+	{"GMT-5", "EST, Eastern US", -5, -4},
+	{"GMT-4", "Atlantic, Canada", -4, 0},
+	{"GMT-3", "Brazilia, Buenos Aries", -3, 0},
+	{"GMT-2", "Mid-Atlantic", -2, 0},
+	{"GMT-1", "Cape Verdes", -1, 0},
+	{"GMT", "Greenwich Mean Time, Greenwich", 0, 0},
+	{"GMT+1", "Berlin, Rome", 1, 0},
+	{"GMT+2", "Israel, Cairo", 2, 0},
+	{"GMT+3", "Moscow, Kuwait", 3, 0},
+	{"GMT+4", "Abu Dhabi, Muscat", 4, 0},
+	{"GMT+5", "Islamabad, Karachi", 5, 0},
+	{"GMT+6", "Almaty, Dhaka", 6, 0},
+	{"GMT+7", "Bangkok, Jakarta", 7, 0},
+	{"GMT+8", "Hong Kong, Beijing", 8, 0},
+	{"GMT+9", "Tokyo, Osaka", 9, 0},
+	{"GMT+10", "Sydney, Melbourne, Guam", 10, 0},
+	{"GMT+11", "Magadan, Soloman Is.", 11, 0},
+	{"GMT+12", "Fiji, Wellington, Auckland", 12, 0}
 };
diff -ur src/tables.h new/tables.h
--- src/tables.h	Sun Apr 27 22:08:25 2003
+++ new/tables.h	Thu May  8 14:57:42 2003
@@ -70,8 +70,10 @@
 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_chars[];
-extern const struct cslot_type cslot_table[];
+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[];
@@ -79,6 +81,7 @@
 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];
 
 struct flag_type
 {
@@ -128,14 +131,16 @@
 struct colour_type
 {
 	const char *name;
-	const char *code;
+	int col_type;
 };
 
 struct cslot_type
 {
 	const char *name;
 	int slot;
-	const char *def;
+	int col_attr;
+	int col_fore;
+	int col_back;
 };
 
 struct vnum_type
@@ -148,6 +153,14 @@
 {
 	const char *name;
 	SPELL_FUN *fun;
+};
+
+struct tzone_type
+{
+	const char *name;
+	const char *zone;
+	int gmt_offset;
+	int dst_offset;
 };
 
 struct gsn_type
diff -ur src/tablesave.c new/tablesave.c
--- src/tablesave.c	Sun Apr 27 22:08:25 2003
+++ new/tablesave.c	Thu May  8 14:57:42 2003
@@ -774,8 +774,8 @@
 			fprintf(fp, "%s\t\t", temp->field);
 			for (i = 0;
 				 i <
-				 (temp->argument ? (int) temp->
-				  argument : *(int *) temp->argument2); i++)
+				 (temp->argument ? (int) temp->argument : *(int *) temp->
+				  argument2); i++)
 				fprintf(fp, "%d ", pbool[i] == TRUE ? 1 : 0);
 			fprintf(fp, "@\n");
 			break;
@@ -802,36 +802,27 @@
 
 void save_commands(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	CMD_DATA *i;
-#if !defined(WIN32)
-	const char *TEMPFILE = COMMAND_FILE ".tmp";
 
-	fp = file_open(TEMPFILE, "w");
-#else
-	fp = file_open(COMMAND_FILE, "w");
-#endif
+	fp = fopen_temp(COMMAND_FILE);
 
 	if (!fp)
 	{
 		perror("save_commands");
-		file_close(fp);
 		return;
 	}
 
 	for (i = cmd_first; i; i = i->next)
 	{
-		fprintf(fp, "#COMMAND\n");
-		save_struct(fp, &cmd, cmdsavetable, i);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#COMMAND\n");
+		save_struct(fp->file, &cmd, cmdsavetable, i);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n\n");
+	fprintf(fp->file, "#!\n\n");
 
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, COMMAND_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_commands(void)
@@ -873,38 +864,29 @@
 
 void save_skills(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	int i;
-#if !defined(WIN32)
-	const char *TEMPFILE = SKILL_FILE ".tmp";
 
-	fp = file_open(TEMPFILE, "w");
-#else
-	fp = file_open(SKILL_FILE, "w");
-#endif
+	fp = fopen_temp(SKILL_FILE);
 
 	if (!fp)
 	{
 		bug("save_skills: NULL fp", 0);
-		file_close(fp);
 		return;
 	}
 
-	fprintf(fp, "%d\n", maxSkill);
+	fprintf(fp->file, "%d\n", maxSkill);
 
 	for (i = 0; i < maxSkill; ++i)
 	{
-		fprintf(fp, "#SKILL\n");
-		save_struct(fp, &sk, skillsavetable, &skill_table[i]);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#SKILL\n");
+		save_struct(fp->file, &sk, skillsavetable, &skill_table[i]);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
+	fprintf(fp->file, "#!\n");
 
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, SKILL_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_skills(void)
@@ -962,15 +944,10 @@
 
 void save_races(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	RACE_DATA *temp;
-#if !defined(WIN32)
-	const char *TEMPFILE = RACE_FILE ".tmp";
 
-	fp = file_open(TEMPFILE, "w");
-#else
-	fp = file_open(RACE_FILE, "w");
-#endif
+	fp = fopen_temp(RACE_FILE);
 
 	if (!fp)
 	{
@@ -980,19 +957,14 @@
 
 	for (temp = race_first; temp; temp = temp->next)
 	{
-		fprintf(fp, "#RACE\n");
-		save_struct(fp, &race, racesavetable, temp);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#RACE\n");
+		save_struct(fp->file, &race, racesavetable, temp);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n\n");
-
-	file_close(fp);
-
-#if !defined(WIN32)
-	rename(TEMPFILE, RACE_FILE);
-#endif
+	fprintf(fp->file, "#!\n\n");
 
+	fclose_temp(fp);
 }
 
 void load_races(void)
@@ -1031,38 +1003,29 @@
 
 void save_groups(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	int i;
-#if !defined(WIN32)
-	const char *TEMPFILE = GROUP_FILE ".tmp";
 
-	fp = file_open(TEMPFILE, "w");
-#else
-	fp = file_open(GROUP_FILE, "w");
-#endif
+	fp = fopen_temp(GROUP_FILE);
 
 	if (!fp)
 	{
 		bug("save_groups: NULL fp", 0);
-		file_close(fp);
 		return;
 	}
 
-	fprintf(fp, "%d\n", maxGroup);
+	fprintf(fp->file, "%d\n", maxGroup);
 
 	for (i = 0; i < maxGroup; ++i)
 	{
-		fprintf(fp, "#GROUP\n");
-		save_struct(fp, &grp, groupsavetable, &group_table[i]);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#GROUP\n");
+		save_struct(fp->file, &grp, groupsavetable, &group_table[i]);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
+	fprintf(fp->file, "#!\n");
 
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, GROUP_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_groups(void)
@@ -1120,38 +1083,29 @@
 
 void save_classes(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	int i;
-#if !defined(WIN32)
-	const char *TEMPFILE = CLASS_FILE ".tmp";
 
-	fp = file_open(TEMPFILE, "w");
-#else
-	fp = file_open(CLASS_FILE, "w");
-#endif
+	fp = fopen_temp(CLASS_FILE);
 
 	if (!fp)
 	{
 		bug("save_classes: NULL fp", 0);
-		file_close(fp);
 		return;
 	}
 
-	fprintf(fp, "%d\n", maxClass);
+	fprintf(fp->file, "%d\n", maxClass);
 
 	for (i = 0; i < maxClass; ++i)
 	{
-		fprintf(fp, "#CLASS\n");
-		save_struct(fp, &cls, classsavetable, &class_table[i]);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#CLASS\n");
+		save_struct(fp->file, &cls, classsavetable, &class_table[i]);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
+	fprintf(fp->file, "#!\n");
 
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, CLASS_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_classes(void)
@@ -1209,36 +1163,27 @@
 
 void save_social_table(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	SOCIAL_DATA *i;
-#if !defined(WIN32)
-	const char *TEMPFILE = SOCIAL_FILE ".tmp";
 
-	fp = file_open(TEMPFILE, "w");
-#else
-	fp = file_open(SOCIAL_FILE, "w");
-#endif
+	fp = fopen_temp(SOCIAL_FILE);
 
 	if (!fp)
 	{
 		bug("save_socials: NULL fp", 0);
-		file_close(fp);
 		return;
 	}
 
 	for (i = social_first; i; i = i->next)
 	{
-		fprintf(fp, "#SOCIAL\n");
-		save_struct(fp, &soc, socialsavetable, i);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#SOCIAL\n");
+		save_struct(fp->file, &soc, socialsavetable, i);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
+	fprintf(fp->file, "#!\n");
 
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, SOCIAL_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_social_table(void)
@@ -1280,36 +1225,27 @@
 
 void save_clans(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	CLAN_DATA *i;
-#if !defined(WIN32)
-	const char *TEMPFILE = CLAN_FILE ".tmp";
 
-	fp = file_open(TEMPFILE, "w");
-#else
-	fp = file_open(CLAN_FILE, "w");
-#endif
+	fp = fopen_temp(CLAN_FILE);
 
 	if (!fp)
 	{
 		bug("save_clans: NULL fp", 0);
-		file_close(fp);
 		return;
 	}
 
 	for (i = clan_first; i; i = i->next)
 	{
-		fprintf(fp, "#CLAN\n");
-		save_struct(fp, &clan, clansavetable, i);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#CLAN\n");
+		save_struct(fp->file, &clan, clansavetable, i);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
+	fprintf(fp->file, "#!\n");
 
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, CLAN_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_clans(void)
@@ -1352,34 +1288,24 @@
 void save_statlist(void)
 {
 	STAT_DATA *pstat;
-	FILE *fp;
-#if !defined(WIN32)
-	const char *TEMPFILE = STAT_FILE ".tmp";
+	FILE_DATA *fp;
 
-	if ((fp = file_open(TEMPFILE, "w")) == NULL)
-#else
-	if ((fp = file_open(STAT_FILE, "w")) == NULL)
-#endif
+	if ((fp = fopen_temp(STAT_FILE)) == NULL)
 	{
 		perror(STAT_FILE);
-		file_close(fp);
 		return;
 	}
 
 	for (pstat = stat_first; pstat != NULL; pstat = pstat->next)
 	{
-		fprintf(fp, "#STAT\n");
-		save_struct(fp, &stat, statsavetable, pstat);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#STAT\n");
+		save_struct(fp->file, &stat, statsavetable, pstat);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
-
-	file_close(fp);
+	fprintf(fp->file, "#!\n");
 
-#if !defined(WIN32)
-	rename(TEMPFILE, STAT_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_statlist(void)
@@ -1416,35 +1342,24 @@
 void save_bans(void)
 {
 	BAN_DATA *pban;
-	FILE *fp;
-#if !defined(WIN32)
-	const char *TEMPFILE = BAN_FILE ".tmp";
+	FILE_DATA *fp;
 
-	if ((fp = file_open(TEMPFILE, "w")) == NULL)
-#else
-	if ((fp = file_open(BAN_FILE, "w")) == NULL)
-#endif
+	if ((fp = fopen_temp(BAN_FILE)) == NULL)
 	{
 		perror(BAN_FILE);
-		file_close(fp);
 		return;
 	}
 
 	for (pban = ban_first; pban != NULL; pban = pban->next)
 	{
-		fprintf(fp, "#BAN\n");
-		save_struct(fp, &ban, bansavetable, pban);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#BAN\n");
+		save_struct(fp->file, &ban, bansavetable, pban);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
+	fprintf(fp->file, "#!\n");
 
-	file_close(fp);
-
-#if !defined(WIN32)
-	rename(TEMPFILE, BAN_FILE);
-	return;
-#endif
+	fclose_temp(fp);
 }
 
 void load_bans(void)
@@ -1480,29 +1395,20 @@
 
 bool save_gquest_data(void)
 {
-	FILE *fp;
-#if !defined(WIN32)
-	char *TEMPFILE = GQUEST_FILE ".tmp";
+	FILE_DATA *fp;
 
-	if (!(fp = file_open(TEMPFILE, "w")))
-#else
-	if (!(fp = file_open(GQUEST_FILE, "w")))
-#endif
+	if (!(fp = fopen_temp(GQUEST_FILE)))
 	{
 		bugf("Could not open file %s in order to save gquest data.",
 			 GQUEST_FILE);
-		file_close(fp);
 		return FALSE;
 	}
 
-	fprintf(fp, "#GQUESTDATA\n");
-	save_struct(fp, &gq, gqsavetable, &gquest_info);
-	fprintf(fp, "#END\n");
-	fprintf(fp, "\n#!\n");
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, GQUEST_FILE);
-#endif
+	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;
 }
 
@@ -1542,36 +1448,27 @@
 
 void save_deities(void)
 {
-	FILE *fp;
+	FILE_DATA *fp;
 	DEITY_DATA *i;
-#if !defined(WIN32)
-	char *TEMPFILE = DEITY_FILE ".tmp";
 
-	fp = file_open(TEMPFILE, "w");
-#else
-	fp = file_open(DEITY_FILE, "w");
-#endif
+	fp = fopen_temp(DEITY_FILE);
 
 	if (!fp)
 	{
 		bug("save_deities: NULL fp", 0);
-		file_close(fp);
 		return;
 	}
 
 	for (i = deity_first; i; i = i->next)
 	{
-		fprintf(fp, "#DEITY\n");
-		save_struct(fp, &deity, deitysavetable, i);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#DEITY\n");
+		save_struct(fp->file, &deity, deitysavetable, i);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
+	fprintf(fp->file, "#!\n");
 
-	file_close(fp);
-#if !defined(WIN32)
-	rename(TEMPFILE, DEITY_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_deities(void)
@@ -1615,34 +1512,24 @@
 void save_webpasses(void)
 {
 	WPWD_DATA *ppwd;
-	FILE *fp;
-#if !defined(WIN32)
-	char *TEMPFILE = WPWD_FILE ".tmp";
+	FILE_DATA *fp;
 
-	if ((fp = file_open(TEMPFILE, "w")) == NULL)
-#else
-	if ((fp = file_open(WPWD_FILE, "w")) == NULL)
-#endif
+	if ((fp = fopen_temp(WPWD_FILE)) == NULL)
 	{
 		perror(WPWD_FILE);
-		file_close(fp);
 		return;
 	}
 
 	for (ppwd = wpwd_first; ppwd != NULL; ppwd = ppwd->next)
 	{
-		fprintf(fp, "#WPWD\n");
-		save_struct(fp, &pwd, pwdsavetable, ppwd);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#WPWD\n");
+		save_struct(fp->file, &pwd, pwdsavetable, ppwd);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
+	fprintf(fp->file, "#!\n");
 
-	file_close(fp);
-
-#if !defined(WIN32)
-	rename(TEMPFILE, WPWD_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_webpasses(void)
@@ -1684,17 +1571,11 @@
 void save_members(void)
 {
 	MBR_DATA *pmbr;
-	FILE *fp;
-#if !defined(WIN32)
-	char *TEMPFILE = MBR_FILE ".tmp";
+	FILE_DATA *fp;
 
-	if ((fp = file_open(TEMPFILE, "w")) == NULL)
-#else
-	if ((fp = file_open(MBR_FILE, "w")) == NULL)
-#endif
+	if ((fp = fopen_temp(MBR_FILE)) == NULL)
 	{
 		perror(MBR_FILE);
-		file_close(fp);
 		return;
 	}
 
@@ -1705,18 +1586,14 @@
 			bugf("%s member data invalid.", pmbr->name);
 			continue;
 		}
-		fprintf(fp, "#MBR\n");
-		save_struct(fp, &mbr, mbrsavetable, pmbr);
-		fprintf(fp, "#END\n\n");
+		fprintf(fp->file, "#MBR\n");
+		save_struct(fp->file, &mbr, mbrsavetable, pmbr);
+		fprintf(fp->file, "#END\n\n");
 	}
 
-	fprintf(fp, "#!\n");
-
-	file_close(fp);
+	fprintf(fp->file, "#!\n");
 
-#if !defined(WIN32)
-	rename(TEMPFILE, MBR_FILE);
-#endif
+	fclose_temp(fp);
 }
 
 void load_members(void)
diff -ur src/update.c new/update.c
--- src/update.c	Sun Apr 27 22:08:25 2003
+++ new/update.c	Thu May  8 14:57:42 2003
@@ -1173,8 +1173,10 @@
 		/* number_range( PULSE_AREA / 2, 3 * PULSE_AREA / 2 ); */
 		area_update();
 		bank_update();
+#if !defined(NO_WEB)
 		if (!WebUP)
 			WebUP = init_web_server();
+#endif
 	}
 
 	if (--pulse_music <= 0)
diff -ur src/war.c new/war.c
--- src/war.c	Sun Apr 27 22:08:25 2003
+++ new/war.c	Thu May  8 14:57:42 2003
@@ -39,37 +39,45 @@
 void make_note(const char *board_name, const char *sender, const char *to,
 			   const char *subject, const int expire_days, const char *text);
 
-#define IS_SET_WAR(ch) (IS_SET((ch)->act, PLR_WAR) || (ch)->pcdata->still_in_war == TRUE)
-
-#define WAR_NONE    0
-#define WAR_RACE    1
-#define WAR_CLASS   2
-#define WAR_GENOCIDE 3
-#define WAR_CLAN    4
-#define MAX_WAR     5
+#define IS_SET_WAR(ch) (!IS_NPC(ch) && (IS_SET((ch)->act, PLR_WAR) || (ch)->pcdata->still_in_war == TRUE))
 
 struct war_type
 {
 	const char *name;
-	int type;
+	const char *plural;
+	enum war_types type;
 };
 
-const struct war_type war_table[] = {
-	{"none", WAR_NONE},
-	{"race", WAR_RACE},
-	{"class", WAR_CLASS},
-	{"genocide", WAR_GENOCIDE},
-	{"clan", WAR_CLAN},
-	{NULL, -1},
+const struct war_type war_table[MAX_WAR] = {
+	{"none", "none", WAR_NONE},
+	{"clan", "clans", WAR_CLAN},
+	{"race", "races", WAR_RACE},
+	{"class", "classes", WAR_CLASS},
+	{"genocide", "people", WAR_GENOCIDE},
+	{"deity", "deities", WAR_DEITY}
 };
 
-char *wartype_name(int type)
+int war_lookup(const char *arg)
 {
 	int i;
 
-	for (i = 0; war_table[i].name != NULL; i++)
+	for (i = WAR_NONE; i < MAX_WAR; i++)
+	{
+		if (is_number(arg) ? atoi(arg) == war_table[i].type
+			: !str_prefix(arg, war_table[i].name))
+			return i;
+	}
+	return -1;
+}
+
+char *wartype_name(int type, bool plural)
+{
+	int i;
+
+	for (i = 0; i < MAX_WAR; i++)
 		if (war_table[i].type == type)
-			return capitalize(war_table[i].name);
+			return capitalize(!plural ? war_table[i].name :
+							  war_table[i].plural);
 
 	return "Unknown";
 }
@@ -124,7 +132,7 @@
 
 	blevel = atoi(arg1);
 	elevel = atoi(arg2);
-	type = atoi(arg3);
+	type = war_lookup(arg3);
 
 	if (blevel <= 0 || blevel > MAX_LEVEL)
 	{
@@ -150,7 +158,7 @@
 		return FALSE;
 	}
 
-	if (type <= WAR_NONE || type >= MAX_WAR)
+	if (type == -1)
 	{
 		int i;
 
@@ -175,7 +183,7 @@
 
 			sprintf(buf,
 					"It costs %d Trivia Points to start a %s war.",
-					WAR_COST, wartype_name(type));
+					WAR_COST, wartype_name(type, FALSE));
 			do_mob_tell(ch, warmaster, buf);
 			return FALSE;
 		}
@@ -184,7 +192,7 @@
 
 			sprintf(buf,
 					"Thank you %s, %s war started, you are %d trivia points lighter.",
-					ch->name, wartype_name(type), WAR_COST);
+					ch->name, wartype_name(type, FALSE), WAR_COST);
 			do_mob_tell(ch, warmaster, buf);
 		}
 	}
@@ -193,15 +201,15 @@
 	replace_string(war_info.who, ch->name);
 	war_info.min_level = blevel;
 	war_info.max_level = elevel;
-	war_info.wartype = type;
+	war_info.wartype = war_table[type].type;
 	announce(ch, INFO_WAR,
 			 "$n announces a %s war for levels %d to %d.  Type 'WAR JOIN' to kill or be killed.",
-			 wartype_name(war_info.wartype), war_info.min_level,
+			 wartype_name(war_info.wartype, FALSE), war_info.min_level,
 			 war_info.max_level);
 	if (ch)
 		chprintf(ch,
 				 "You announce a %s war for levels %d to %d.  Type 'WAR JOIN' to kill or be killed.",
-				 wartype_name(war_info.wartype), war_info.min_level,
+				 wartype_name(war_info.wartype, FALSE), war_info.min_level,
 				 war_info.max_level);
 	war_info.timer = 3;
 	war_info.next = 0;
@@ -277,9 +285,11 @@
 	war_info.max_level = maxlvl;
 
 	if (clan >= 2)
-		war_info.wartype = number_range(WAR_NONE, MAX_WAR - 1);
+		war_info.wartype =
+			(enum war_types) number_range(WAR_NONE + 1, MAX_WAR - 1);
 	else
-		war_info.wartype = number_range(WAR_NONE, MAX_WAR - 2);
+		war_info.wartype =
+			(enum war_types) number_range(WAR_CLAN + 1, MAX_WAR - 1);
 
 	if (war_info.wartype == WAR_NONE)
 		war_info.wartype = WAR_GENOCIDE;
@@ -287,13 +297,13 @@
 	announce(warmaster, INFO_WAR,
 			 "%s %s war for levels %d to %d%s.  Type 'WAR JOIN' to kill or be killed.",
 			 !warmaster ? "A" : "$n announces a",
-			 wartype_name(war_info.wartype), war_info.min_level,
+			 wartype_name(war_info.wartype, FALSE), war_info.min_level,
 			 war_info.max_level, !warmaster ? " has started" : "");
 	if (warmaster)
 		chprintf(warmaster,
 				 "You announce a %s war for levels %d"
 				 " to %d.  Type 'WAR JOIN' to kill or be killed.",
-				 wartype_name(war_info.wartype), war_info.min_level,
+				 wartype_name(war_info.wartype, FALSE), war_info.min_level,
 				 war_info.max_level);
 	war_info.timer = 3;
 	war_info.next = 0;
@@ -351,12 +361,42 @@
 	case WAR_CLASS:
 		return class_table[ch->Class[0]].name;
 	case WAR_GENOCIDE:
-		return "";
+		return ch->name;
 	case WAR_CLAN:
 		return ch->clan->who_name;
+	case WAR_DEITY:
+		return ch->deity->name;
+	}
+}
+
+void *wartype_data(CHAR_DATA * ch)
+{
+	switch (war_info.wartype)
+	{
+	default:
+		return NULL;
+	case WAR_RACE:
+		return ch->race;
+	case WAR_CLASS:
+		return &ch->Class[0];
+	case WAR_GENOCIDE:
+		return &ch->id;
+	case WAR_CLAN:
+		return ch->clan;
+	case WAR_DEITY:
+		return ch->deity;
 	}
 }
 
+char *warrior_status(CHAR_DATA * ch)
+{
+	if (war_info.wartype != WAR_GENOCIDE)
+		return FORMATF("%s (%s, Lvl %d)", ch->name, wartype_info(ch),
+					   ch->level);
+	else
+		return FORMATF("%s (Lvl %d)", ch->name, ch->level);
+}
+
 CH_CMD(do_war)
 {
 	char arg[MIL];
@@ -449,7 +489,7 @@
 				   war_info.iswar == WAR_WAITING ? "Waiting" : "Running",
 				   war_info.timer);
 		chprintlnf(ch, "{RType        : {W%s war.{x",
-				   wartype_name(war_info.wartype));
+				   wartype_name(war_info.wartype, FALSE));
 		chprintlnf(ch, "{g%s{x", draw_line(ch, NULL, 0));
 		return;
 	}
@@ -465,8 +505,8 @@
 			if (IS_SET(wch->act, PLR_WAR))
 			{
 				chprintf(ch,
-						 "{W%-12s : [{R%ld%% hit{W] [{M%ld%% mana{W] [Pos: {G%s{W]{x",
-						 wch == ch ? "You" : wch->name,
+						 "{W%s : [{R%ld%% hit{W] [{M%ld%% mana{W] [Pos: {G%s{W]{x",
+						 warrior_status(wch),
 						 wch->hit * 100 / wch->max_hit,
 						 wch->mana * 100 / wch->max_mana,
 						 position_flags[wch->position].name);
@@ -535,13 +575,7 @@
 			char_to_room(ch, location);
 			ch->pcdata->still_in_war = TRUE;
 			SET_BIT(ch->act, PLR_WAR);
-			if (war_info.wartype == WAR_GENOCIDE)
-				announce(NULL, INFO_WAR,
-						 "%s (Level %d) joins the war!", ch->name, ch->level);
-			else
-				announce(NULL, INFO_WAR,
-						 "%s (Level %d, %s) joins the war!",
-						 ch->name, ch->level, wartype_info(ch));
+			announce(NULL, INFO_WAR, "%s joins the war!", warrior_status(ch));
 			act("$n arrives to get $s ass whipped!", ch, NULL, NULL, TO_ROOM);
 			war_info.inwar++;
 			do_function(ch, &do_look, "auto");
@@ -552,7 +586,7 @@
 	return;
 }
 
-bool abort_race_war(void)
+bool abort_war(void)
 {
 	CHAR_DATA *ch;
 	CHAR_DATA *vict;
@@ -565,57 +599,7 @@
 			{
 				if (IS_SET(vict->act, PLR_WAR))
 				{
-					if (ch->race == vict->race)
-						continue;
-					else
-						return FALSE;
-				}
-			}
-		}
-	}
-	return TRUE;
-}
-
-bool abort_class_war(void)
-{
-	CHAR_DATA *ch;
-	CHAR_DATA *vict;
-
-	for (ch = player_first; ch != NULL; ch = ch->next_player)
-	{
-		if (IS_SET(ch->act, PLR_WAR))
-		{
-			for (vict = player_first; vict != NULL; vict = vict->next_player)
-			{
-				if (IS_SET(vict->act, PLR_WAR))
-				{
-					if (prime_class(ch) == prime_class(vict))
-						continue;
-					else
-						return FALSE;
-				}
-			}
-		}
-	}
-	return TRUE;
-}
-
-bool abort_clan_war(void)
-{
-	CHAR_DATA *ch;
-	CHAR_DATA *vict;
-
-	for (ch = player_first; ch != NULL; ch = ch->next_player)
-	{
-		if (IS_SET(ch->act, PLR_WAR) && is_clan(ch))
-		{
-			for (vict = player_first; vict != NULL; vict = vict->next_player)
-			{
-				if (IS_SET(vict->act, PLR_WAR) && is_clan(vict))
-				{
-					if (is_same_clan(ch, vict))
-						continue;
-					else
+					if (wartype_data(ch) != wartype_data(vict))
 						return FALSE;
 				}
 			}
@@ -634,49 +618,40 @@
 		return;
 
 	output = new_buf();
-	add_buf(output, "{WWAR INFO{g\n\r--------{x");
-	sprintf(buf, "{RStarted by  : {W%s",
+	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", war_info.min_level,
+	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", wartype_name(war_info.wartype));
+	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");
+	add_buf(output, "{WWAR COMBATENTS{g\n\r--------------{x\n\r");
 	for (wch = player_first; wch != NULL; wch = wch->next_player)
 	{
 		if (!IS_SET_WAR(wch))
 			continue;
-		if (war_info.wartype != 3)
-			sprintf(buf, "{W%12s : (%s){x", wch->name, wartype_info(wch));
-		else
-			sprintf(buf, "{W%s{x", wch->name);
+
+		sprintf(buf, "{W%s{x\n\r", warrior_status(wch));
 		add_buf(output, buf);
 	}
-	add_buf(output, "{g--------------{x");
+	add_buf(output, "{g--------------{x\n\r");
 	switch (war_info.wartype)
 	{
 	case WAR_RACE:
-		sprintf(buf, "{WThe {R%s's{W won this war.{x", ch->race->name);
-		add_buf(output, buf);
-		break;
 	case WAR_CLASS:
-		sprintf(buf, "{WThe {R%s's{W won this war.{x",
-				class_table[ch->Class[0]].name);
-		add_buf(output, buf);
-		break;
-	case WAR_GENOCIDE:
-		sprintf(buf, "{R%s{W won the Genocide war.{x", ch->name);
+		sprintf(buf, "{WThe {R%s's{W won this war.{x\n\r", wartype_info(ch));
 		add_buf(output, buf);
 		break;
-	case WAR_CLAN:
-		sprintf(buf, "{R%s{W won this war.{x", ch->clan->who_name);
+	default:
+		sprintf(buf, "{R%s{W won this war.{x\n\r", wartype_info(ch));
 		add_buf(output, buf);
 		break;
 	}
 
-	sprintf(subject, "War Info %s", ctime(&current_time));
+	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);
 	make_note("General", sender, "All", subject, 15, buf_string(output));
@@ -704,7 +679,7 @@
 					 "%d minute%s left to join the war. (Levels %d - %d, %s War)",
 					 war_info.timer, war_info.timer == 1 ? "" : "s",
 					 war_info.min_level, war_info.max_level,
-					 wartype_name(war_info.wartype));
+					 wartype_name(war_info.wartype, FALSE));
 		}
 		else
 		{
@@ -713,20 +688,11 @@
 				end_war();
 				announce(NULL, INFO_WAR, "Not enough people for war.");
 			}
-			else if (war_info.wartype == WAR_RACE && abort_race_war())
+			else if (abort_war())
 			{
+				announce(NULL, INFO_WAR, "Not enough %s for war.",
+						 wartype_name(war_info.wartype, TRUE));
 				end_war();
-				announce(NULL, INFO_WAR, "Not enough races for war.");
-			}
-			else if (war_info.wartype == WAR_CLASS && abort_class_war())
-			{
-				end_war();
-				announce(NULL, INFO_WAR, "Not enough classes for war.");
-			}
-			else if (war_info.wartype == WAR_CLAN && abort_clan_war())
-			{
-				end_war();
-				announce(NULL, INFO_WAR, "Not enough clans for war");
 			}
 			else
 			{
@@ -819,93 +785,36 @@
 	announce(NULL, INFO_WAR, "%s was killed in combat by %s!{x",
 			 victim->name, ch->name);
 
-	switch (war_info.wartype)
+	if (abort_war())
 	{
-	case WAR_RACE:
-		if (abort_race_war())
+		switch (war_info.wartype)
 		{
-			announce(NULL, INFO_WAR, "The %s's have won the War!",
-					 ch->race->name);
-			note_war(ch);
-			for (wch = player_first; wch != NULL; wch = wch->next_player)
-			{
-				if (!IS_SET_WAR(wch))
-					continue;
-
-				if (wch->race == ch->race)
-				{
-					wch->gold += reward;
-					wch->pcdata->questpoints += qreward;
-					chprintf(wch,
-							 "You recieve %d gold and %d questpoints from the war tribunal!",
-							 reward, qreward);
-				}
-			}
-			end_war();
-			return;
-		}						// end abort
-		break;
-	case WAR_CLASS:
-		if (abort_class_war())
-		{
-			announce(NULL, INFO_WAR, "The %s's have won the War!{x",
-					 class_table[ch->Class[0]].name);
-			note_war(ch);
-			for (wch = player_first; wch != NULL; wch = wch->next_player)
-			{
-				if (!IS_SET_WAR(wch))
-					continue;
-				if (wch->Class[0] == ch->Class[0])
-				{
-					wch->gold += reward;
-					wch->pcdata->questpoints += qreward;
-					chprintf(wch,
-							 "You recieve %d gold and %d questpoints from the war tribunal!",
-							 reward, qreward);
-				}
-			}
-			end_war();
-			return;
+		case WAR_RACE:
+		case WAR_CLASS:
+			announce(NULL, INFO_WAR, "The %s's have won the war!",
+					 wartype_info(ch));
+			break;
+		default:
+			announce(NULL, INFO_WAR, "%s has won the war!", wartype_info(ch));
+			break;
 		}
-		break;
-	case WAR_CLAN:
-		if (abort_clan_war())
+		note_war(ch);
+		for (wch = player_first; wch != NULL; wch = wch->next_player)
 		{
-			announce(NULL, INFO_WAR, "%s has won the War!{x",
-					 ch->clan->who_name);
-			note_war(ch);
-			for (wch = player_first; wch != NULL; wch = wch->next_player)
+			if (!IS_SET_WAR(wch))
+				continue;
+
+			if (wartype_data(wch) == wartype_data(ch))
 			{
-				if (!IS_SET_WAR(wch))
-					continue;
-				if (is_same_clan(ch, wch))
-				{
-					wch->gold += reward;
-					wch->pcdata->questpoints += qreward;
-					chprintf(wch,
-							 "You recieve %d gold and %d questpoints from the war tribunal!",
-							 reward, qreward);
-				}
+				wch->gold += reward;
+				wch->pcdata->questpoints += qreward;
+				chprintf(wch,
+						 "You recieve %d gold and %d questpoints from the war tribunal!",
+						 reward, qreward);
 			}
-			end_war();
-			return;
 		}
-		break;
-	case WAR_GENOCIDE:
-		if (war_info.inwar == 1)
-		{
-			announce(ch, INFO_WAR, "$n has won the War!");
-			chprintln(ch, "You have won the War!");
-			note_war(ch);
-			ch->gold += reward;
-			ch->pcdata->questpoints += qreward;
-			chprintf(ch,
-					 "You recieve %d gold and %d questpoints from the war tribunal!",
-					 reward, qreward);
-			end_war();
-			return;
-		}
-		break;
+		end_war();
+		return;
 	}
 	return;
 }
@@ -918,16 +827,7 @@
 	if (!IS_IN_WAR(ch) || !IS_IN_WAR(wch))
 		return FALSE;
 
-	if (war_info.wartype == WAR_GENOCIDE)
-		return FALSE;
-
-	if (war_info.wartype == WAR_RACE && ch->race == wch->race)
-		return TRUE;
-
-	if (war_info.wartype == WAR_CLASS && ch->Class[0] == wch->Class[0])
-		return TRUE;
-
-	if (war_info.wartype == WAR_CLAN && is_same_clan(ch, wch))
+	if (wartype_data(ch) == wartype_data(wch))
 		return TRUE;
 
 	return FALSE;
@@ -974,17 +874,7 @@
 				announce(ch, INFO_WAR, "$n has left. War over.");
 				end_war();
 			}
-			if (abort_race_war())
-			{
-				announce(ch, INFO_WAR, "$n has left. War over.");
-				end_war();
-			}
-			else if (abort_class_war())
-			{
-				announce(ch, INFO_WAR, "$n has left. War over.");
-				end_war();
-			}
-			else if (abort_clan_war())
+			if (abort_war())
 			{
 				announce(ch, INFO_WAR, "$n has left. War over.");
 				end_war();
diff -ur src/webserver.c new/webserver.c
--- src/webserver.c	Sun Apr 27 22:08:25 2003
+++ new/webserver.c	Thu May  8 14:57:42 2003
@@ -198,6 +198,8 @@
 	return FALSE;
 }
 
+#if !defined(NO_WEB)
+
 /* Thanks to John Ludeman for this code...
  * Define translation matrix for Base64 decode.
  * it's fast and const should make it shared text page.
@@ -2540,3 +2542,5 @@
 		free_mem(current);
 	}
 }
+
+#endif
diff -ur src/webserver.h new/webserver.h
--- src/webserver.h	Sun Apr 27 22:08:25 2003
+++ new/webserver.h	Thu May  8 14:57:42 2003
@@ -32,6 +32,8 @@
 #include "../win32/winstuff.h"
 #endif
 
+#if !defined(NO_WEB)
+
 #define DOCTYPE "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
 
 /*
@@ -86,3 +88,5 @@
 bool init_web_server(void);
 void update_web_server(void);
 void shutdown_web_server(void);
+
+#endif