1stMUD/corefiles/
1stMUD/gods/
1stMUD/notes/
1stMUD/player/
1stMUD/win32/
1stMUD/win32/ROM/
diff -ur src/Makefile new/Makefile
--- src/Makefile	Thu Mar 20 14:55:19 2003
+++ new/Makefile	Thu Mar 27 02:12:19 2003
@@ -2,7 +2,7 @@
 PROF    = -ggdb3
 WARN    = -Wall -Werror
 LIBS	= -lcrypt -lz
-D_FLAGS = #-DNO_MCCP
+D_FLAGS = -DNO_STRHASH #-DNO_MCCP
 C_FLAGS = $(WARN) $(PROF) $(D_FLAGS)
 L_FLAGS = $(PROF) $(LIBS)
 
diff -ur src/Makefile.linux new/Makefile.linux
--- src/Makefile.linux	Tue Mar 18 15:39:48 2003
+++ new/Makefile.linux	Wed Mar 26 21:20:55 2003
@@ -2,7 +2,7 @@
 PROF    = -ggdb3
 WARN    = -Wall -Werror
 LIBS	= -lcrypt -lz
-D_FLAGS = #-DNO_MCCP
+D_FLAGS = #-DNO_STRHASH -DNO_MCCP
 C_FLAGS = $(WARN) $(PROF) $(D_FLAGS)
 L_FLAGS = $(PROF) $(LIBS)
 
diff -ur src/Makefile.normal new/Makefile.normal
--- src/Makefile.normal	Tue Mar 18 15:39:48 2003
+++ new/Makefile.normal	Wed Mar 26 21:20:56 2003
@@ -2,7 +2,7 @@
 PROF    = -ggdb3
 WARN    = -Wall -Werror
 LIBS	= -lz
-D_FLAGS = #-DNO_MCCP
+D_FLAGS = #-DNO_STRHASH -DNO_MCCP
 C_FLAGS = $(WARN) $(PROF) $(D_FLAGS)
 L_FLAGS = $(PROF) $(LIBS)
 
diff -ur src/Makefile.solaris new/Makefile.solaris
--- src/Makefile.solaris	Tue Mar 18 15:39:48 2003
+++ new/Makefile.solaris	Wed Mar 26 21:20:58 2003
@@ -2,7 +2,7 @@
 PROF    = -ggdb3
 WARN    = -Wall -Werror
 LIBS    = -lsocket -lresolv -lnsl -lz
-D_FLAGS = #-DNO_MCCP
+D_FLAGS = #-DNO_STRHASH -DNO_MCCP
 C_FLAGS = $(WARN) $(PROF) $(D_FLAGS)
 L_FLAGS = $(PROF) $(LIBS)
 
diff -ur src/act_comm.c new/act_comm.c
--- src/act_comm.c	Thu Mar 20 17:32:37 2003
+++ new/act_comm.c	Thu Mar 27 02:17:54 2003
@@ -286,8 +286,7 @@
 		{
 			CHAR_DATA *victim;
 			char buf[MIL + 200];
-			int cmd;
-			bool found;
+			SOCIAL_DATA *cmd;
 			char argx[MIL];
 
 			argument = one_argument(argument, command);
@@ -298,35 +297,19 @@
 					 "{W<Channel> + <social> is used for channel based socials.{x");
 				return;
 			}
-			found = FALSE;
-			if (!str_cmp(command, "random"))
-				cmd = number_range(1, maxSocial - 1);
-			else
+			if (!(cmd = find_social(command)))
 			{
-				for (cmd = 0; cmd < maxSocial; cmd++)
-				{
-					if (command[0] == social_table[cmd].name[0]
-						&& !str_prefix(command, social_table[cmd].name))
-					{
-						found = TRUE;
-						break;
-					}
-				}
-				if (!found)
-				{
-					chprintln(ch, "{WWhat kind of social is that?!?!{x");
-					return;
-				}
+				chprintln(ch, "{WWhat kind of social is that?!?!{x");
+				return;
 			}
 			one_argument(argument, argx);
 			victim = NULL;
 			if (IS_NULLSTR(argx))
 			{
-				sprintf(buf, "%s %s", type, social_table[cmd].char_no_arg);
+				sprintf(buf, "%s %s", type, cmd->char_no_arg);
 				act_new(buf, ch, NULL, NULL, TO_CHAR, POS_DEAD);
 				channel_social(ch, NULL, bitname,
-							   social_table[cmd].others_no_arg, type,
-							   spec_flag, last_type);
+							   cmd->others_no_arg, type, spec_flag, last_type);
 			}
 			else if ((victim = get_char_world(ch, argx)) == NULL)
 			{
@@ -342,26 +325,25 @@
 				}
 				if (victim == ch)
 				{
-					sprintf(buf, "%s %s", type, social_table[cmd].char_auto);
+					sprintf(buf, "%s %s", type, cmd->char_auto);
 					act_new(buf, ch, NULL, NULL, TO_CHAR, POS_DEAD);
 					channel_social(ch, victim, bitname,
-								   social_table[cmd].others_auto, type,
+								   cmd->others_auto, type,
 								   spec_flag, last_type);
 				}
 				else
 				{
-					sprintf(buf, "%s %s", type, social_table[cmd].char_found);
+					sprintf(buf, "%s %s", type, cmd->char_found);
 					act_new(buf, ch, NULL, victim, TO_CHAR, POS_DEAD);
 					if ((!bitname || !IS_SET(victim->comm, bitname))
 						&& !IS_SET(victim->comm, COMM_NOGOCIAL)
 						&& display_channel(ch, victim, spec_flag))
 					{
-						sprintf(buf, "%s %s", type,
-								social_table[cmd].vict_found);
+						sprintf(buf, "%s %s", type, cmd->vict_found);
 						act_new(buf, ch, NULL, victim, TO_VICT, POS_DEAD);
 					}
 					channel_social(ch, victim, bitname,
-								   social_table[cmd].others_found, type,
+								   cmd->others_found, type,
 								   spec_flag, last_type);
 				}
 			}
@@ -689,14 +671,17 @@
 /* clan channels */
 CH_CMD(do_clantalk)
 {
-	if (!is_clan(ch) || clan_table[ch->clan].independent)
+	char buf[MSL];
+
+	if (!is_clan(ch) || ch->clan->independent)
 	{
 		chprintln(ch, "You aren't in a clan.");
 		return;
 	}
 
-	public_ch(ch, argument, "{r[{RClan{r]{Y", COMM_NOCLAN, spec_clan_flag,
-			  LAST_CLANTALK);
+	sprintf(buf, "%s{W (%s)", ch->clan->who_name,
+			ch->clan->rank[ch->rank].rankname);
+	public_ch(ch, argument, buf, COMM_NOCLAN, spec_clan_flag, LAST_CLANTALK);
 }
 
 CH_CMD(do_immtalk)
diff -ur src/act_enter.c new/act_enter.c
--- src/act_enter.c	Thu Mar 20 17:32:37 2003
+++ new/act_enter.c	Thu Mar 27 02:17:54 2003
@@ -235,7 +235,7 @@
 CH_CMD(do_worship)
 {
 	CHAR_DATA *priest;
-	int i;
+	DEITY_DATA *i;
 
 	if (IS_NULLSTR(argument))
 	{
@@ -246,9 +246,8 @@
 
 	if (!str_cmp(argument, "list"))
 	{
-		for (i = 0; i < maxDeity; i++)
-			chprintlnf(ch, "\t%-12s : %s", deity_table[i].name,
-					   deity_table[i].desc);
+		for (i = deity_first; i; i = i->next)
+			chprintlnf(ch, "\t%-12s : %s", i->name, i->desc);
 
 		return;
 	}
@@ -272,14 +271,14 @@
 
 	i = deity_lookup(argument);
 
-	if (i == -1)
+	if (i == NULL)
 	{
 		chprintln(ch, "That deity doesn't exist.");
 		return;
 	}
 
 	ch->deity = i;
-	chprintlnf(ch, "You now worship %s.", deity_table[i].name);
+	chprintlnf(ch, "You now worship %s.", i->name);
 	ch->pcdata->questpoints -= 250;
 	return;
 }
diff -ur src/act_info.c new/act_info.c
--- src/act_info.c	Thu Mar 20 17:32:37 2003
+++ new/act_info.c	Thu Mar 27 02:17:54 2003
@@ -593,14 +593,14 @@
 /* RT does socials */
 CH_CMD(do_socials)
 {
-	int iSocial;
+	SOCIAL_DATA *iSocial;
 	int col;
 
 	col = 0;
 
-	for (iSocial = 0; social_table[iSocial].name != NULL; iSocial++)
+	for (iSocial = social_first; iSocial != NULL; iSocial = iSocial->next)
 	{
-		chprintf(ch, "%-12s", social_table[iSocial].name);
+		chprintf(ch, "%-12s", iSocial->name);
 		if (++col % 6 == 0)
 			chprintln(ch, "");
 	}
@@ -1469,7 +1469,7 @@
 			   "" CTAG(_SCORE1) "Race: " CTAG(_SCORE2) "%s"
 			   CTAG(_SCORE1) "  Sex: " CTAG(_SCORE2) "%s"
 			   CTAG(_SCORE1) "  Class: " CTAG(_SCORE2) "%s{x",
-			   race_table[ch->race].name,
+			   ch->race->name,
 			   ch->sex == 0 ? "sexless" : ch->sex == 1 ? "male" : "female",
 			   IS_NPC(ch) ? "mobile" : class_long(ch));
 
@@ -1528,9 +1528,8 @@
 	chprintlnf(ch,
 			   "" CTAG(_SCORE2) "You worship " CTAG(_SCORE2) "%s, %s"
 			   CTAG(_SCORE1) ".{x",
-			   ch->deity != -1 ? deity_table[ch->deity].name : "Mota",
-			   ch->deity !=
-			   -1 ? deity_table[ch->deity].desc : "the God of Thera");
+			   ch->deity != NULL ? ch->deity->name : "Mota",
+			   ch->deity != NULL ? ch->deity->desc : "the God of Thera");
 
 	{
 		int rcnt = roomcount(ch);
@@ -2027,8 +2026,7 @@
 	if (!is_clan(ch))
 		return "";
 
-	sprintf(buf, "[%s] %s ", clan_table[ch->clan].rank[ch->rank].shortname,
-			clan_table[ch->clan].who_name);
+	sprintf(buf, " %s", ch->clan->who_name);
 	return buf;
 }
 
@@ -2089,10 +2087,9 @@
 	else
 		sprintf(block,
 				"[" CTAG(_WLEVEL) "%03d " CTAG(_WRACE) "%6s " CTAG(_WCLASS)
-				"%s{x] ", wch->level, race_table[wch->race].who_name, Class);
+				"%s{x] ", wch->level, wch->race->who_name, Class);
 
 	sprintf(buf, "%s%s%s%s%s%s%s%s%s%s%s%s\n\r", block,
-			format_clan(wch),
 			wch->incog_level >= LEVEL_HERO ? "(Incog) " : "",
 			wch->invis_level >= LEVEL_HERO ? "(Wizi) " : "",
 			IS_SET(wch->comm, COMM_AFK) ? "[AFK] " : "",
@@ -2101,7 +2098,7 @@
 													  PLR_WAR) ? "(WAR) " :
 			"", IS_SET(wch->act, PLR_KILLER) ? "(KILLER) " : "",
 			IS_SET(wch->act, PLR_THIEF) ? "(THIEF) " : "", wch->name,
-			IS_NPC(wch) ? "" : wch->pcdata->title);
+			IS_NPC(wch) ? "" : wch->pcdata->title, format_clan(wch));
 	return (buf);
 }
 
@@ -2255,16 +2252,14 @@
 	BUFFER *output;
 	DESCRIPTOR_DATA *d;
 	int iClass;
-	int iRace;
-	int iClan;
+	RACE_DATA *iRace;
+	CLAN_DATA *iClan;
 	int iLevelLower;
 	int iLevelUpper;
 	int nNumber;
 	int nMatch, count = 0, immcount = 0;
 	int ndesc, totalcount = 0, imminvis = 0;
 	bool *rgfClass;
-	bool *rgfRace;
-	bool *rgfClan;
 	bool fClassRestrict = FALSE;
 	bool fClanRestrict = FALSE;
 	bool fClan = FALSE;
@@ -2283,12 +2278,6 @@
 	alloc_mem(rgfClass, bool, maxClass);
 	for (iClass = 0; iClass < maxClass; iClass++)
 		rgfClass[iClass] = FALSE;
-	alloc_mem(rgfRace, bool, maxRace);
-	for (iRace = 0; iRace < maxRace; iRace++)
-		rgfRace[iRace] = FALSE;
-	alloc_mem(rgfClan, bool, maxClan);
-	for (iClan = 0; iClan < maxClan; iClan++)
-		rgfClan[iClan] = FALSE;
 
 	/*
 	 * Parse arguments.
@@ -2316,8 +2305,6 @@
 				break;
 			default:
 				chprintln(ch, "Only two level numbers allowed.");
-				free_mem(rgfClan);
-				free_mem(rgfRace);
 				free_mem(rgfClass);
 				return;
 			}
@@ -2339,26 +2326,22 @@
 				{
 					iRace = race_lookup(arg);
 
-					if (iRace == -1 || iRace >= maxRace
-						|| !race_table[iRace].pc_race)
+					if (iRace == NULL || !iRace->pc_race)
 					{
 						if (!str_prefix(arg, "clan"))
 							fClan = TRUE;
 						else
 						{
 							iClan = clan_lookup(arg);
-							if (iClan != -1 && iClan < maxClan)
+							if (iClan != NULL)
 							{
 								fClanRestrict = TRUE;
-								rgfClan[iClan] = TRUE;
 							}
 							else
 							{
 								chprintln
 									(ch,
 									 "That's not a valid race, class, or clan.");
-								free_mem(rgfClan);
-								free_mem(rgfRace);
 								free_mem(rgfClass);
 								return;
 							}
@@ -2367,7 +2350,6 @@
 					else
 					{
 						fRaceRestrict = TRUE;
-						rgfRace[iRace] = TRUE;
 					}
 				}
 				else
@@ -2423,10 +2405,9 @@
 			(fImmortalOnly && wch->level < LEVEL_IMMORTAL) ||
 			(fClassRestrict && !rgfClass[wch->Class[0]]) || (fRaceRestrict
 															 &&
-															 !rgfRace
-															 [wch->race])
+															 iRace != wch->race)
 			|| (fClan && !is_clan(wch)) || (fClanRestrict
-											&& !rgfClan[wch->clan]))
+											&& wch->clan != iClan))
 			continue;
 
 		charitems[nMatch].pch = wch;
@@ -2490,8 +2471,6 @@
 		add_buf(output, "There is a Global Quest running you can join.\n\r");
 	page_to_char(buf_string(output), ch);
 	free_buf(output);
-	free_mem(rgfClan);
-	free_mem(rgfRace);
 	free_mem(rgfClass);
 	return;
 }
@@ -2914,26 +2893,17 @@
 	if (argument[0] == '\0')
 	{
 		int col;
-		struct skill_type *skills = NULL;
 
 		col = 0;
-		alloc_mem(skills, struct skill_type, maxSkill + 1);
-
-		skills =
-			(struct skill_type *) memcpy(skills, skill_table,
-										 sizeof(struct skill_type) * maxSkill +
-										 1);
-
-		qsort(skills, maxSkill, sizeof(skill_table[0]), srt_skills);
 		for (sn = 0; sn < maxSkill; sn++)
 		{
-			if (skills[sn].name == NULL)
+			if (skill_table[sn].name == NULL)
 				break;
 			if (!can_use_skpell(ch, sn) || ch->pcdata->learned[sn] < 1	/* skill is not known */
 				)
 				continue;
 
-			chprintf(ch, "%-18s %3d%%  ", skills[sn].name,
+			chprintf(ch, "%-18s %3d%%  ", skill_table[sn].name,
 					 ch->pcdata->learned[sn]);
 			if (++col % 3 == 0)
 				chprintln(ch, "");
@@ -2942,7 +2912,6 @@
 		if (col % 3 != 0)
 			chprintln(ch, "");
 
-		free_mem(skills);
 		chprintlnf(ch, "You have %d practice sessions left.", ch->practice);
 	}
 	else
diff -ur src/act_obj.c new/act_obj.c
--- src/act_obj.c	Thu Mar 20 17:32:37 2003
+++ new/act_obj.c	Thu Mar 27 02:17:55 2003
@@ -1847,8 +1847,7 @@
 	{
 		chprintlnf(ch,
 				   "%s gives you %d silver coins for your sacrifice.",
-				   ch->deity == -1 ? "Mota" : deity_table[ch->deity].name,
-				   silver);
+				   ch->deity == NULL ? "Mota" : ch->deity->name, silver);
 	}
 
 	ch->silver += silver;
diff -ur src/act_wiz.c new/act_wiz.c
--- src/act_wiz.c	Thu Mar 20 17:32:37 2003
+++ new/act_wiz.c	Thu Mar 27 02:17:55 2003
@@ -183,7 +183,7 @@
 {
 	char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
 	CHAR_DATA *victim;
-	int clan;
+	CLAN_DATA *clan;
 
 	argument = one_argument(argument, arg1);
 	argument = one_argument(argument, arg2);
@@ -203,29 +203,29 @@
 	{
 		chprintln(ch, "They are now clanless.");
 		chprintln(victim, "You are now a member of no clan!");
-		victim->clan = -1;
+		victim->clan = NULL;
 		victim->rank = 0;
 		update_members(victim, TRUE);
 		return;
 	}
 
-	if ((clan = clan_lookup(arg2)) == -1)
+	if ((clan = clan_lookup(arg2)) == NULL)
 	{
 		chprintln(ch, "No such clan exists.");
 		return;
 	}
 
-	if (clan_table[clan].independent)
+	if (clan->independent)
 	{
-		chprintlnf(ch, "They are now a %s.", clan_table[clan].name);
-		chprintlnf(victim, "You are now a %s.", clan_table[clan].name);
+		chprintlnf(ch, "They are now a %s.", clan->name);
+		chprintlnf(victim, "You are now a %s.", clan->name);
 	}
 	else
 	{
 		chprintlnf(ch, "They are now a member of clan %s.",
-				   capitalize(clan_table[clan].name));
+				   capitalize(clan->name));
 		chprintlnf(victim, "You are now a member of clan %s.\n\r",
-				   capitalize(clan_table[clan].name));
+				   capitalize(clan->name));
 	}
 
 	if (is_clan(victim))
@@ -1485,9 +1485,10 @@
 	chprintlnf(ch,
 			   "Vnum: %ld  Format: %s  Race: %s  Group: %d  Sex: %s  Room: %ld",
 			   IS_NPC(victim) ? victim->pIndexData->vnum : 0,
-			   IS_NPC(victim) ? victim->pIndexData->
-			   new_format ? "new" : "old" : "pc", race_table[victim->race].name,
-			   IS_NPC(victim) ? victim->group : 0, sex_table[victim->sex].name,
+			   IS_NPC(victim) ? victim->
+			   pIndexData->new_format ? "new" : "old" : "pc",
+			   victim->race->name, IS_NPC(victim) ? victim->group : 0,
+			   sex_table[victim->sex].name,
 			   victim->in_room == NULL ? 0 : victim->in_room->vnum);
 
 	if (IS_NPC(victim))
@@ -3644,11 +3645,11 @@
 
 	if (!str_prefix(arg2, "clan"))
 	{
-		int clan;
+		CLAN_DATA *clan;
 
 		clan = clan_lookup(arg3);
 
-		if (clan == -1)
+		if (clan == NULL)
 		{
 			chprintln(ch, "Thats not a valid clan.");
 			return;
@@ -3673,17 +3674,17 @@
 	}
 	if (!str_prefix(arg2, "race"))
 	{
-		int race;
+		RACE_DATA *race;
 
 		race = race_lookup(arg3);
 
-		if (race == 0)
+		if (race == NULL)
 		{
 			chprintln(ch, "That is not a valid race.");
 			return;
 		}
 
-		if (!IS_NPC(victim) && !race_table[race].pc_race)
+		if (!IS_NPC(victim) && !race->pc_race)
 		{
 			chprintln(ch, "That is not a valid player race.");
 			return;
@@ -4093,8 +4094,8 @@
 			count++;
 			sprintf(buf + strlen(buf), "[%3d %2d] %s@%s\n\r",
 					d->descriptor, d->connected,
-					d->original ? d->original->name : d->character ? d->
-					character->name : "(none)", d->host);
+					d->original ? d->original->name : d->
+					character ? d->character->name : "(none)", d->host);
 		}
 	}
 	if (count == 0)
diff -ur src/board.c new/board.c
--- src/board.c	Thu Mar 20 17:32:37 2003
+++ new/board.c	Thu Mar 27 02:17:55 2003
@@ -540,7 +540,7 @@
 		chprintlnf
 			(ch,
 			 "\n\rEnter text. Type {W%cq{x or {W@{x on an empty line to end note, or {W%ch{x for help.\n\r"
-			 "======================================================================",
+			 "======================================================================\n\r",
 			 STR_EDIT_KEY(ch), STR_EDIT_KEY(ch));
 
 		ch->desc->connected = CON_NOTE_TEXT;
@@ -1015,7 +1015,7 @@
 			write_to_buffer(d, buf, 0);
 			sprintf(buf,
 					"\n\rEnter text. Type {W%cq{x or {W@{x on an empty line to end note, or {W%ch{x for help.\n\r"
-					"======================================================================\n\r",
+					"======================================================================\n\r\n\r",
 					STR_EDIT_KEY(ch), STR_EDIT_KEY(ch));
 			write_to_buffer(d, buf, 0);
 			d->connected = CON_NOTE_TEXT;
@@ -1068,7 +1068,7 @@
 
 	sprintf(buf,
 			"\n\rEnter text. Type {W%cq{x or {W@{x on an empty line to end note, or {W%ch{x for help.\n\r"
-			"======================================================================",
+			"======================================================================\n\r\n\r",
 			STR_EDIT_KEY(ch), STR_EDIT_KEY(ch));
 	write_to_buffer(d, buf, 0);
 	d->connected = CON_NOTE_TEXT;
diff -ur src/clans.c new/clans.c
--- src/clans.c	Thu Mar 20 17:32:37 2003
+++ new/clans.c	Thu Mar 27 02:17:55 2003
@@ -102,20 +102,20 @@
 	if (victim->rank > rank)
 	{
 		chprintlnf(ch, "They have been demoted to %s.",
-				   clan_table[victim->clan].rank[rank].rankname);
+				   victim->clan->rank[rank].rankname);
 		chprintlnf(victim, "You have been demoted to %s, by %s.",
-				   clan_table[victim->clan].rank[rank].rankname, ch->name);
+				   victim->clan->rank[rank].rankname, ch->name);
 		victim->rank = rank;
 		update_members(victim, FALSE);
 	}
 	else
 	{
 		chprintlnf(ch, "They are now a %s of clan %s.",
-				   clan_table[victim->clan].rank[rank].rankname,
-				   capitalize(clan_table[victim->clan].name));
+				   victim->clan->rank[rank].rankname,
+				   capitalize(victim->clan->name));
 		chprintlnf(victim, "You are now a %s of clan %s.",
-				   clan_table[victim->clan].rank[rank].rankname,
-				   capitalize(clan_table[victim->clan].name));
+				   victim->clan->rank[rank].rankname,
+				   capitalize(victim->clan->name));
 		victim->rank = rank;
 		update_members(victim, FALSE);
 	}
@@ -123,16 +123,16 @@
 
 CH_CMD(do_clist)
 {
-	int i;
+	CLAN_DATA *i;
 	MBR_DATA *pmbr;
 	char buf[MSL];
 	char buf2[MSL];
 
 	chprintln(ch, "Clans available:");
 	chprintln(ch, draw_line(NULL, 0));
-	for (i = 0; i < maxClan; i++)
+	for (i = clan_first; i; i = i->next)
 	{
-		chprint(ch, clan_table[i].who_name);
+		chprint(ch, i->who_name);
 		buf[0] = '\0';
 		buf2[0] = '\0';
 		for (pmbr = mbr_first; pmbr != NULL; pmbr = pmbr->next)
@@ -155,7 +155,8 @@
 
 CH_CMD(do_cinfo)
 {
-	int i, r;
+	int r;
+	CLAN_DATA *i;
 
 	if (argument[0] == '\0')
 	{
@@ -163,24 +164,21 @@
 		return;
 	}
 
-	if ((i = clan_lookup(argument)) == -1)
+	if ((i = clan_lookup(argument)) == NULL)
 	{
 		chprintln(ch, "That is not a valid clan.");
 		return;
 	}
 
-	chprintlnf(ch, "Name    : %s", clan_table[i].name);
-	chprintlnf(ch, "WhoName : %s", clan_table[i].who_name);
-	chprintlnf(ch, "Indep   : %s",
-			   clan_table[i].independent ? "TRUE" : "FALSE");
+	chprintlnf(ch, "Name    : %s", i->name);
+	chprintlnf(ch, "WhoName : %s", i->who_name);
+	chprintlnf(ch, "Indep   : %s", i->independent ? "TRUE" : "FALSE");
 	if (IS_IMMORTAL(ch))
-		chprintlnf(ch, "Hall    : %ld", clan_table[i].hall);
+		chprintlnf(ch, "Hall    : %ld", i->hall);
 
 	for (r = 0; r < MAX_RANK; r++)
 	{
-		chprintlnf(ch, "Rank %d : %s [%s]", r + 1,
-				   clan_table[i].rank[r].rankname,
-				   clan_table[i].rank[r].shortname);
+		chprintlnf(ch, "Rank %d : %s", r + 1, i->rank[r].rankname);
 	}
 }
 
@@ -189,7 +187,7 @@
 	CHAR_DATA *victim;
 	ROOM_INDEX_DATA *location;
 
-	if (!is_clan(ch) || clan_table[ch->clan].independent)
+	if (!is_clan(ch) || ch->clan->independent)
 	{
 		chprintln(ch, "You're not in a clan.");
 		return;
@@ -207,7 +205,7 @@
 
 	act("$n prays for transportation!", ch, 0, 0, TO_ROOM);
 
-	if ((location = get_room_index(clan_table[ch->clan].hall)) == NULL)
+	if ((location = get_room_index(ch->clan->hall)) == NULL)
 	{
 		chprintln(ch, "Your clan doesnt seem to have a clan hall.");
 		return;
@@ -266,12 +264,12 @@
 {
 	CHAR_DATA *victim;
 	char arg1[MIL];
-	int clan;
+	CLAN_DATA *clan;
 
 	if (IS_NPC(ch))
 		return;
 
-	if ((!is_clan(ch) || clan_table[ch->clan].independent || !is_leader(ch))
+	if ((!is_clan(ch) || ch->clan->independent || !is_leader(ch))
 		&& !IS_IMMORTAL(ch))
 	{
 		chprintln(ch, "You must be a valid clan leader to use this command.");
@@ -303,7 +301,7 @@
 	{
 		char arg2[MIL];
 
-		if ((clan = clan_lookup(arg1)) == -1)
+		if ((clan = clan_lookup(arg1)) == NULL)
 		{
 			chprintln(ch, "Invalid clan.");
 			return;
@@ -359,7 +357,7 @@
 				continue;
 
 			chprintlnf(ch, "%3d %12s %12s", mbr->level, mbr->name,
-					   clan_table[mbr->clan].rank[mbr->rank].rankname);
+					   mbr->clan->rank[mbr->rank].rankname);
 			found = TRUE;
 		}
 		if (!found)
@@ -384,19 +382,19 @@
 			chprintln(ch, "You're stuck...only a god can help you now!");
 			return;
 		}
-		if (is_clan(victim) && !clan_table[victim->clan].independent)
+		if (is_clan(victim) && !victim->clan->independent)
 		{
 			chprintln(ch, "They are in a clan already.");
 			return;
 		}
-		if (victim->invited != -1)
+		if (victim->invited != NULL)
 		{
 			chprintln(ch, "They have already been invited to join a clan.");
 			return;
 		}
 		chprintlnf(ch, "%s has been invited to join your clan.", victim->name);
 		chprintlnf(victim, "{RYou have been invited to join {x%s{x",
-				   clan_table[clan].who_name);
+				   clan->who_name);
 		chprintln(victim, "{YUse {Gjoin accept{Y to join this clan,{x");
 		chprintln(victim, "{Yor {Gjoin deny{Y to turn down the invitation.{x");
 		victim->invited = clan;
@@ -433,7 +431,7 @@
 		chprintln(ch, "They are now clanless.");
 		chprintln(victim, "Your clan leader has kicked you out!");
 		update_members(victim, TRUE);
-		victim->clan = -1;
+		victim->clan = NULL;
 		victim->rank = 0;
 		char_from_room(victim);
 		char_to_room(victim, get_room_index(ROOM_VNUM_TEMPLE));
@@ -456,13 +454,13 @@
 		return;
 	}
 
-	if (is_clan(ch) && !clan_table[ch->clan].independent)
+	if (is_clan(ch) && !ch->clan->independent)
 	{
 		chprintln(ch, "You are already in a clan.");
 		return;
 	}
 
-	if (ch->invited == -1)
+	if (ch->invited == NULL)
 	{
 		chprintln(ch, "You have not been invited to join a clan.");
 		return;
@@ -474,14 +472,13 @@
 			 victim = victim->next_player)
 			if (is_clan(victim) && victim->clan == ch->invited)
 				chprintlnf(victim, "%s accepts the invitation to join %s.",
-						   PERS(ch, victim), clan_table[victim->clan].name);
+						   PERS(ch, victim), victim->clan->name);
 
 		ch->clan = ch->invited;
 		ch->rank = 0;
 		chprintlnf(ch, "{RYou are now a %s of {x%s{x",
-				   clan_table[ch->clan].rank[ch->rank].rankname,
-				   clan_table[ch->clan].who_name);
-		ch->invited = -1;
+				   ch->clan->rank[ch->rank].rankname, ch->clan->who_name);
+		ch->invited = NULL;
 		update_members(ch, FALSE);
 		return;
 	}
@@ -493,9 +490,9 @@
 			if (is_clan(victim) && victim->clan == ch->invited
 				&& victim->rank >= MAX_RANK - 2)
 				chprintlnf(victim, "%s denies the invitation to join %s.",
-						   PERS(ch, victim), clan_table[victim->clan].name);
+						   PERS(ch, victim), victim->clan->name);
 
-		ch->invited = -1;
+		ch->invited = NULL;
 		return;
 	}
 	else
@@ -524,7 +521,7 @@
 			save_members();
 		}
 	}
-	if (pdelete || !is_clan(ch) || clan_table[ch->clan].independent)
+	if (pdelete || !is_clan(ch) || ch->clan->independent)
 		return;
 
 	curr = new_mbr();
@@ -539,7 +536,8 @@
 
 CH_CMD(do_roster)
 {
-	int i, clan, count = 0;
+	int i, count = 0;
+	CLAN_DATA *clan;
 	MBR_DATA *pmbr;
 	char buf[MSL], buf2[MSL];
 	char arg[MIL];
@@ -581,13 +579,13 @@
 		return;
 	}
 
-	if ((clan = clan_lookup(arg)) == -1)
+	if ((clan = clan_lookup(arg)) == NULL)
 	{
 		chprintln(ch, "That clan does not exist.");
 		return;
 	}
 
-	if (clan_table[clan].independent)
+	if (clan->independent)
 	{
 		chprintln(ch, "That is not a real clan.");
 		return;
@@ -595,12 +593,10 @@
 
 	chprintlnf(ch, "{W%s{x\n\r",
 			   stringf(0, ALIGN_CENTER, "-", FORMATF("[ %s{W Roster ]",
-													 clan_table
-													 [clan].who_name)));
+													 clan->who_name)));
 	for (i = MAX_RANK - 1; i >= 0; i--)
 	{
-		chprintf(ch, "%s%12ss {W:%s", rcol[i],
-				 clan_table[clan].rank[i].rankname, rcol[i]);
+		chprintf(ch, "%s%12ss {W:%s", rcol[i], clan->rank[i].rankname, rcol[i]);
 		buf[0] = '\0';
 		buf2[0] = '\0';
 		count = 0;
diff -ur src/comm.c new/comm.c
--- src/comm.c	Thu Mar 20 17:32:37 2003
+++ new/comm.c	Thu Mar 27 02:17:55 2003
@@ -1577,8 +1577,8 @@
 						((!IS_NPC(ch) &&
 						  IS_SET(ch->act, PLR_HOLYLIGHT)) ||
 						 (!IS_AFFECTED(ch, AFF_BLIND) &&
-						  !room_is_dark(ch->in_room))) ? ch->in_room->
-						name : "darkness");
+						  !room_is_dark(ch->in_room))) ? ch->
+						in_room->name : "darkness");
 			else
 				sprintf(buf2, " ");
 			i = buf2;
@@ -1731,7 +1731,7 @@
  */
 bool check_parse_name(const char *name)
 {
-	int clan;
+	CLAN_DATA *clan;
 
 	/*
 	 * Reserved words.
@@ -1743,10 +1743,10 @@
 	}
 
 	/* check clans */
-	for (clan = 0; clan < maxClan; clan++)
+	for (clan = clan_first; clan; clan = clan->next)
 	{
-		if (LOWER(name[0]) == LOWER(clan_table[clan].name[0]) &&
-			!str_cmp(name, clan_table[clan].name))
+		if (LOWER(name[0]) == LOWER(clan->name[0]) &&
+			!str_cmp(name, clan->name))
 			return FALSE;
 	}
 
@@ -1879,8 +1879,8 @@
 			dold->connected != CON_GET_NAME &&
 			dold->connected != CON_GET_OLD_PASSWORD &&
 			!str_cmp(name,
-					 dold->original ? dold->original->name : dold->character->
-					 name))
+					 dold->original ? dold->original->name : dold->
+					 character->name))
 		{
 			write_to_buffer(d, "That character is already playing.\n\r", 0);
 			write_to_buffer(d, "Do you wish to connect anyway (Y/N)?", 0);
@@ -2165,26 +2165,26 @@
 					log_string("perform_act:bad code $S for 'vch'");
 				break;
 			case 'g':
-				if (ch && ch->deity != -1)
-					i = deity_table[ch->deity].name;
+				if (ch && ch->deity != NULL)
+					i = ch->deity->name;
 				else
 					log_string("perform_act:bad code $g for 'ch'");
 				break;
 			case 'G':
-				if (vch && vch->deity != -1)
-					i = deity_table[vch->deity].name;
+				if (vch && vch->deity != NULL)
+					i = vch->deity->name;
 				else
 					log_string("perform_act:bad code $G for 'vch'");
 				break;
 			case 'c':
-				if (ch && ch->clan != -1)
-					i = clan_table[ch->clan].name;
+				if (ch && ch->clan != NULL)
+					i = ch->clan->name;
 				else
 					log_string("perform_act:bad code $c for 'ch'");
 				break;
 			case 'C':
-				if (vch && vch->clan != -1)
-					i = clan_table[vch->clan].name;
+				if (vch && vch->clan != NULL)
+					i = vch->clan->name;
 				else
 					log_string("perform_act:bad code $C for 'vch'");
 				break;
@@ -2398,26 +2398,26 @@
 					log_string("perform_act:bad code $S for 'vch'");
 				break;
 			case 'g':
-				if (ch && ch->deity != -1)
-					i = deity_table[ch->deity].name;
+				if (ch && ch->deity != NULL)
+					i = ch->deity->name;
 				else
 					log_string("perform_act:bad code $g for 'ch'");
 				break;
 			case 'G':
-				if (vch && vch->deity != -1)
-					i = deity_table[vch->deity].name;
+				if (vch && vch->deity != NULL)
+					i = vch->deity->name;
 				else
 					log_string("perform_act:bad code $G for 'vch'");
 				break;
 			case 'c':
-				if (ch && ch->clan != -1)
-					i = clan_table[ch->clan].name;
+				if (ch && ch->clan != NULL)
+					i = ch->clan->name;
 				else
 					log_string("perform_act:bad code $c for 'ch'");
 				break;
 			case 'C':
-				if (vch && vch->clan != -1)
-					i = clan_table[vch->clan].name;
+				if (vch && vch->clan != NULL)
+					i = vch->clan->name;
 				else
 					log_string("perform_act:bad code $C for 'vch'");
 				break;
diff -ur src/db.c new/db.c
--- src/db.c	Thu Mar 20 17:32:37 2003
+++ new/db.c	Thu Mar 27 02:17:55 2003
@@ -69,7 +69,9 @@
 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)
 char *string_hash[MAX_KEY_HASH];
+#endif
 
 AREA_DATA *area_first;
 AREA_DATA *area_last;
@@ -96,8 +98,6 @@
 int mobile_count = 0;
 const char *help_greeting;
 
-struct clan_type *clan_table;
-
 /*
  * Semi-locals.
  */
@@ -137,7 +137,7 @@
 	 */
 	{
 		log_string("Allocating String Space...");
-		top_string = strspace_alloc();
+		strspace_alloc();
 		fBootDb = TRUE;
 	}
 
@@ -346,6 +346,8 @@
 		load_deities();
 		log_string("Loading web passwords...");
 		load_webpasses();
+		build_command_hash();
+		build_social_hash();
 		logf("Sorted %d socials.", sort_socials());
 		logf("Sorted %d helps.", sort_helps());
 		logf("Stored %d Areas, %d Rooms, %d Mobs & %d Objects", top_area,
@@ -368,17 +370,12 @@
 	pArea->file_name = fread_string(fp);
 
 	pArea->area_flags = AREA_LOADING;	/* OLC */
-	pArea->security = 9;		/* OLC *//* 9 -- Hugin */
-	pArea->vnum = top_area;		/* OLC */
 	free_string(pArea->name);
 	pArea->name = fread_string(fp);
 	free_string(pArea->credits);
 	pArea->credits = fread_string(fp);
 	pArea->min_vnum = fread_number(fp);
 	pArea->max_vnum = fread_number(fp);
-	pArea->age = 15;
-	pArea->nplayer = 0;
-	pArea->empty = FALSE;
 
 	LINK(pArea, area_first, area_last, next, prev);
 	current_area = pArea;
@@ -431,16 +428,8 @@
 	bool fMatch;
 
 	pArea = new_area();
-	pArea->age = 15;
-	pArea->nplayer = 0;
 	free_string(pArea->file_name);
 	pArea->file_name = str_dup(strArea);
-	pArea->vnum = top_area;
-	pArea->security = 9;		/* 9 -- Hugin */
-	pArea->min_vnum = 0;
-	pArea->max_vnum = 0;
-	pArea->area_flags = 0;
-/*  pArea->recall       = ROOM_VNUM_TEMPLE;        ROM OLC */
 
 	for (;;)
 	{
@@ -545,7 +534,7 @@
 {
 	MOB_INDEX_DATA *pMobIndex;
 	/* for race updating */
-	int race;
+	RACE_DATA *race;
 	char name[MAX_STRING_LENGTH];
 
 	if (!current_area)			/* OLC */
@@ -643,7 +632,7 @@
 		/* compute the race BS */
 		one_argument(pMobIndex->player_name, name);
 
-		if (name[0] == '\0' || (race = race_lookup(name)) == 0)
+		if (name[0] == '\0' || (race = race_lookup(name)) == NULL)
 		{
 			/* fill in with blanks */
 			pMobIndex->race = race_lookup("human");
@@ -662,13 +651,12 @@
 		{
 			pMobIndex->race = race;
 			pMobIndex->off_flags =
-				OFF_DODGE | OFF_DISARM | OFF_TRIP | ASSIST_RACE |
-				race_table[race].off;
-			pMobIndex->imm_flags = race_table[race].imm;
-			pMobIndex->res_flags = race_table[race].res;
-			pMobIndex->vuln_flags = race_table[race].vuln;
-			pMobIndex->form = race_table[race].form;
-			pMobIndex->parts = race_table[race].parts;
+				OFF_DODGE | OFF_DISARM | OFF_TRIP | ASSIST_RACE | race->off;
+			pMobIndex->imm_flags = race->imm;
+			pMobIndex->res_flags = race->res;
+			pMobIndex->vuln_flags = race->vuln;
+			pMobIndex->form = race->form;
+			pMobIndex->parts = race->parts;
 		}
 
 		if (letter != 'S')
@@ -995,10 +983,9 @@
 		}
 		fBootDb = TRUE;
 
-		alloc_mem(pRoomIndex, ROOM_INDEX_DATA, 1);
 		pRoomIndex = new_room_index();
 		pRoomIndex->first_person = NULL;
-		pRoomIndex->clan = -1;
+		pRoomIndex->clan = NULL;
 		pRoomIndex->first_content = NULL;
 		pRoomIndex->first_extra_descr = NULL;
 		pRoomIndex->area = current_area;
@@ -1038,7 +1025,7 @@
 			{
 				const char *tmp;
 
-				if (pRoomIndex->clan > -1)
+				if (pRoomIndex->clan != NULL)
 				{
 					bug("Load_rooms: duplicate clan fields.", 0);
 					exit(1);
@@ -2683,6 +2670,7 @@
  */
 const char *fread_string(FILE * fp)
 {
+#if !defined(NO_STRHASH)
 	char *plast;
 	char c;
 
@@ -2784,105 +2772,105 @@
 			}
 		}
 	}
-}
-
-const char *fread_string_eol(FILE * fp)
-{
-	static bool char_special[256 - EOF];
-	char *plast;
+#else
+#define MLR	MSL*8
+	char buf[MLR + 2];			/* extra 2 bytes on the end for \0 and 1b slack */
 	char c;
+	long i = 0;
+	bool sFull = FALSE;
 
-	if (char_special[EOF - EOF] != TRUE)
-	{
-		char_special[EOF - EOF] = TRUE;
-		char_special['\n' - EOF] = TRUE;
-		char_special['\r' - EOF] = TRUE;
-	}
-
-	plast = top_string + sizeof(char *);
-	if (plast > &string_space[MAX_STRING - MAX_STRING_LENGTH])
-	{
-		bug("Fread_string: MAX_STRING %d exceeded.", MAX_STRING);
-		exit(1);
-	}
-
-	/*
-	 * Skip blanks.
-	 * Read first char.
-	 */
+	/* skip blanks */
 	do
 	{
 		c = getc(fp);
 	}
 	while (isspace(c));
 
-	if ((*plast++ = c) == '\n')
+	/* empty string */
+	if (c == '~')
 		return &str_empty[0];
 
+	buf[i] = c;
+	i++;
+
 	for (;;)
 	{
-		if (!char_special[(*plast++ = getc(fp)) - EOF])
-			continue;
+		if (i >= MLR && !sFull)
+		{
+			bugf("String [%20.20s...] exceeded [%d] MLR", buf, MLR);
+			sFull = TRUE;
+		}
 
-		switch (plast[-1])
+		switch (c = getc(fp))
 		{
 		default:
+			if (!sFull)
+			{
+				buf[i] = c;
+				i++;
+			}
 			break;
 
 		case EOF:
-			bug("Fread_string_eol  EOF", 0);
-			exit(1);
+			/* temp fix */
+			bugf("Fread_string: String [%20.20s...] EOF", buf);
+			return &str_empty[0];
 			break;
 
 		case '\n':
-		case '\r':
+			if (!sFull)
 			{
-				union
-				{
-					char *pc;
-					char rgc[sizeof(char *)];
-				}
-				u1;
-				unsigned int ic;
-				int iHash;
-				char *pHash;
-				char *pHashPrev;
-				char *pString;
+				buf[i] = '\n';
+				i++;
+				buf[i] = '\r';
+				i++;
+			}
+			break;
 
-				plast[-1] = '\0';
-				iHash = UMIN(MAX_KEY_HASH - 1, plast - 1 - top_string);
-				for (pHash = string_hash[iHash]; pHash; pHash = pHashPrev)
-				{
-					for (ic = 0; ic < sizeof(char *); ic++)
-						u1.rgc[ic] = pHash[ic];
-					pHashPrev = u1.pc;
-					pHash += sizeof(char *);
+		case '\r':
+			break;
 
-					if (top_string[sizeof(char *)] == pHash[0] &&
-						!strcmp(top_string + sizeof(char *) + 1, pHash + 1))
-						return pHash;
-				}
+		case '~':
+			buf[i] = '\0';
+			return str_dup(buf);
+			break;
+		}
+	}
+#endif
+}
 
-				if (fBootDb)
-				{
-					pString = top_string;
-					top_string = plast;
-					u1.pc = string_hash[iHash];
-					for (ic = 0; ic < sizeof(char *); ic++)
-						pString[ic] = u1.rgc[ic];
-					string_hash[iHash] = pString;
+const char *freadline(FILE * fp)
+{
+	static char buf[MSL];
+	char c;
+	int pos = 0;
 
-					nAllocString += 1;
-					sAllocString += top_string - pString;
-					return pString + sizeof(char *);
-				}
-				else
-				{
-					return str_dup(top_string + sizeof(char *));
-				}
-			}
+	buf[0] = '\0';				/* reset strlen to 0 */
+
+	for (;;)
+	{
+		c = fgetc(fp);			/* get one char from file */
+		if (c == '\n' || c == '\r')	/* if CR or LF return the string */
+		{
+			return buf;			/* return the string */
+		}
+		else					/* else add one char to string */
+		{
+			buf[pos] = c;		/* insert c into string */
+			pos++;
+			buf[pos] = '\0';	/* add one char to string */
+		}
+
+		if (pos >= MSL)			/* check so we don't overflow */
+		{
+			buf[MSL] = '\0';	/* trim string to MSL */
+			ungetc(c, fp);		/* go 1 char back */
+			return buf;			/* return the string */
 		}
 	}
+	/* just in case - return empty string if we get somehow here */
+	buf[0] = '\0';
+	return buf;
 }
 
 /*
@@ -2962,8 +2950,10 @@
 	if (str[0] == '\0')
 		return &str_empty[0];
 
+#if !defined(NO_STRHASH)
 	if (str >= string_space && str < top_string)
 		return str;
+#endif
 
 	alloc_mem(str_new, char, strlen(str) + 1);
 	strcpy(str_new, str);
@@ -2977,8 +2967,12 @@
  */
 void free_string(const char *pstr)
 {
-	if (pstr == NULL || pstr == &str_empty[0] ||
-		(pstr >= string_space && pstr < top_string))
+	if (pstr == NULL || pstr == &str_empty[0]
+#if !defined(NO_STRHASH)
+		|| (pstr >= string_space && pstr < top_string))
+#else
+		)
+#endif
 		return;
 
 	free_mem(pstr);
diff -ur src/db.h new/db.h
--- src/db.h	Thu Mar 20 17:32:38 2003
+++ new/db.h	Thu Mar 27 02:17:55 2003
@@ -29,13 +29,15 @@
 #if !defined(DB_H)
 #define DB_H
 
+#if !defined(NO_STRHASH)
 #define			MAX_STRING	    4000*1024
+#endif
 
 /* conversion from db.h */
 void convert_mob(MOB_INDEX_DATA * mob);
 void convert_obj(OBJ_INDEX_DATA * obj);
 
-char *strspace_alloc();
+void strspace_alloc();
 
 /* macro for flag swapping */
 #define GET_UNSET(flag1,flag2)	(~(flag1)&((flag1)|(flag2)))
diff -ur src/db2.c new/db2.c
--- src/db2.c	Thu Mar 20 17:32:37 2003
+++ new/db2.c	Thu Mar 27 02:17:55 2003
@@ -109,10 +109,8 @@
 		pMobIndex->race = race_lookup(tmp);
 		free_string(tmp);
 
-		pMobIndex->act =
-			fread_flag(fp) | ACT_IS_NPC | race_table[pMobIndex->race].act;
-		pMobIndex->affected_by =
-			fread_flag(fp) | race_table[pMobIndex->race].aff;
+		pMobIndex->act = fread_flag(fp) | ACT_IS_NPC | pMobIndex->race->act;
+		pMobIndex->affected_by = fread_flag(fp) | pMobIndex->race->aff;
 		pMobIndex->pShop = NULL;
 		pMobIndex->alignment = fread_number(fp);
 		pMobIndex->group = fread_number(fp);
@@ -149,11 +147,10 @@
 		pMobIndex->ac[AC_EXOTIC] = fread_number(fp) * 10;
 
 		/* read flags and add in data from the race table */
-		pMobIndex->off_flags = fread_flag(fp) | race_table[pMobIndex->race].off;
-		pMobIndex->imm_flags = fread_flag(fp) | race_table[pMobIndex->race].imm;
-		pMobIndex->res_flags = fread_flag(fp) | race_table[pMobIndex->race].res;
-		pMobIndex->vuln_flags =
-			fread_flag(fp) | race_table[pMobIndex->race].vuln;
+		pMobIndex->off_flags = fread_flag(fp) | pMobIndex->race->off;
+		pMobIndex->imm_flags = fread_flag(fp) | pMobIndex->race->imm;
+		pMobIndex->res_flags = fread_flag(fp) | pMobIndex->race->res;
+		pMobIndex->vuln_flags = fread_flag(fp) | pMobIndex->race->vuln;
 
 		/* vital statistics */
 		pMobIndex->start_pos = position_lookup(fread_word(fp));
@@ -162,8 +159,8 @@
 
 		pMobIndex->wealth = fread_number(fp);
 
-		pMobIndex->form = fread_flag(fp) | race_table[pMobIndex->race].form;
-		pMobIndex->parts = fread_flag(fp) | race_table[pMobIndex->race].parts;
+		pMobIndex->form = fread_flag(fp) | pMobIndex->race->form;
+		pMobIndex->parts = fread_flag(fp) | pMobIndex->race->parts;
 		/* size */
 		CHECK_POS(pMobIndex->size, size_lookup(fread_word(fp)), "size");
 /*	pMobIndex->size			= size_lookup(fread_word(fp)); */
@@ -955,10 +952,11 @@
 CH_CMD(do_memory_heap)
 {
 	chprint(ch, separator);
-
+#if !defined(NO_STRHASH)
 	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);
+#endif
 	chprintlnf(ch, " Perms %d blocks of %ld kb.",
 			   nAllocPerm, sAllocPerm / 1024);
 
@@ -1032,15 +1030,19 @@
 		(*iFun) (ch, argument);
 }
 
-char *strspace_alloc()
+void strspace_alloc()
 {
+#if !defined(NO_STRHASH)
+	extern char *top_string;
+
 	if ((string_space = (char *) calloc(1, MAX_STRING)) == NULL)
 	{
 		logf("Unable to allocate %d kB string space from system.",
 			 MAX_STRING / 1024);
 		exit(1);
 	}
-	return string_space;
+	top_string = string_space;
+#endif
 }
 
 /* Function Name: FILE *file_open (const char *mode, char *fmt,...)
@@ -1341,19 +1343,6 @@
 	}
 }
 
-int srt_socials(const void *p1, const void *p2)
-{
-	struct social_type soc1 = *(struct social_type *) p1;
-	struct social_type soc2 = *(struct social_type *) p2;
-
-	if (IS_NULLSTR(soc1.name))
-		return 2;
-	else if (IS_NULLSTR(soc2.name))
-		return 1;
-
-	return strcmp(soc1.name, soc2.name);
-}
-
 int srt_skills(const void *p1, const void *p2)
 {
 	struct skill_type sk1;
@@ -1372,84 +1361,66 @@
 
 int sort_socials(void)
 {
-	qsort((void *) social_table, maxSocial, sizeof(social_table[0]),
-		  srt_socials);
+	SOCIAL_DATA *tmp, *tmp_next, **socials;
+	int i = 0, j;
 
-	return maxSocial;
-}
+	alloc_mem(socials, SOCIAL_DATA *, maxSocial);
 
-int srt_helps(const void *p1, const void *p2)
-{
-	struct help_data hlp1 = *(struct help_data *) p1;
-	struct help_data hlp2 = *(struct help_data *) p2;
+	for (tmp = social_first; tmp; tmp = tmp_next)
+	{
+		tmp_next = tmp->next;
+		socials[i++] = tmp;
+		UNLINK(tmp, social_first, social_last, next, prev);
+	}
 
-	if (IS_NULLSTR(hlp1.keyword))
-		return 2;
-	else if (IS_NULLSTR(hlp2.keyword))
-		return 1;
-	else
-		return strcmp(hlp1.keyword, hlp2.keyword);
+	for (j = 0; j < i; j++)
+	{
+		for (tmp = social_first; tmp; tmp = tmp->next)
+		{
+			if (strcmp(socials[j]->name, tmp->name) < 0)
+			{
+				INSERT(socials[j], tmp, social_first, next, prev);
+				break;
+			}
+		}
+
+		if (!tmp)
+			LINK(socials[j], social_first, social_last, next, prev);
+	}
+	free_mem(socials);
+	return i;
 }
 
 int sort_helps(void)
 {
-	struct help_data *helps;
-	HELP_DATA *pHelp;
-	HELP_DATA *pMark;
-	int i = 0;
-	int iMark = top_help;
-
-	alloc_mem(helps, struct help_data, top_help);
+	HELP_DATA *tmp, *tmp_next, **helps;
+	int i = 0, j;
 
-	for (pHelp = help_first; pHelp; pHelp = pHelp->next)
-		helps[i++] = *pHelp;
+	alloc_mem(helps, HELP_DATA *, top_help);
 
-	qsort(helps, top_help - 1, sizeof(*helps), srt_helps);
-
-	for (pHelp = help_first; pHelp; pHelp = pMark)
+	for (tmp = help_first; tmp; tmp = tmp_next)
 	{
-		pMark = pHelp->next;
-		if (pHelp)
-			free_help(pHelp);
+		tmp_next = tmp->next;
+		helps[i++] = tmp;
+		UNLINK(tmp, help_first, help_last, next, prev);
 	}
 
-	help_first = NULL;
-	help_last = NULL;
-
-	for (i = 0; i < iMark; i++)
+	for (j = 0; j < i; j++)
 	{
-		pHelp = new_help();
-
-		memcpy(pHelp, &helps[i], sizeof(*helps));
+		for (tmp = help_first; tmp; tmp = tmp->next)
+		{
+			if (strcmp(helps[j]->keyword, tmp->keyword) < 0)
+			{
+				INSERT(helps[j], tmp, help_first, next, prev);
+				break;
+			}
+		}
 
-		LINK(pHelp, help_first, help_last, next, prev);
+		if (!tmp)
+			LINK(helps[j], help_first, help_last, next, prev);
 	}
-
-	top_help = iMark;
 	free_mem(helps);
-	return iMark;
-
-}
-
-int srt_cmds(const void *p1, const void *p2)
-{
-	struct cmd_type cmd1 = *(struct cmd_type *) p1;
-	struct cmd_type cmd2 = *(struct cmd_type *) p2;
-
-	return cmd2.level - cmd1.level;
-}
-
-int srt_cmds_name(const void *p1, const void *p2)
-{
-	struct cmd_type cmd1 = *(struct cmd_type *) p1;
-	struct cmd_type cmd2 = *(struct cmd_type *) p2;
-
-	if (IS_NULLSTR(cmd1.name))
-		return 2;
-	else if (IS_NULLSTR(cmd2.name))
-		return 1;
-
-	return strcmp(cmd1.name, cmd2.name);
+	return i;
 }
 
 #define                 MAX_PERM_BLOCK  131072
@@ -1488,4 +1459,116 @@
 	sAllocPerm += sMem;
 
 	return pMem;
+}
+
+void build_command_hash(void)
+{
+	CMD_DATA *tmp, *tmp_next;
+
+	for (tmp = cmd_first; tmp; tmp = tmp_next)
+	{
+		tmp_next = tmp->next;
+
+		add_command(tmp);
+	}
+}
+
+void build_social_hash(void)
+{
+	SOCIAL_DATA *tmp, *tmp_next;
+
+	for (tmp = social_first; tmp; tmp = tmp_next)
+	{
+		tmp_next = tmp->next;
+
+		add_social(tmp);
+	}
+}
+
+void add_command(CMD_DATA * command)
+{
+	int hash;
+
+	if (!command)
+	{
+		bug("add_command: NULL command", 0);
+		return;
+	}
+
+	if (!command->name)
+	{
+		bug("add_command: NULL command->name", 0);
+		return;
+	}
+
+	if (!command->do_fun)
+	{
+		bug("add_command: NULL command->do_fun", 0);
+		return;
+	}
+
+	hash = LOWER(command->name[0]) % 126;
+
+	LINK_LAST(command, next_hash, CMD_DATA, command_hash[hash]);
+
+	return;
+}
+
+void unlink_command(CMD_DATA * command)
+{
+	int hash;
+
+	if (!command)
+	{
+		bug("unlink_command: NULL command", 0);
+		return;
+	}
+
+	hash = LOWER(command->name[0]) % 126;
+
+	UNLINK_SINGLE(command, next_hash, CMD_DATA, command_hash[hash]);
+}
+
+void unlink_social(SOCIAL_DATA * social)
+{
+	int hash;
+
+	if (!social)
+	{
+		bug("unlink_social: NULL social", 0);
+		return;
+	}
+
+	if (LOWER(social->name[0]) < 'a' || LOWER(social->name[0]) > 'z')
+		hash = 0;
+	else
+		hash = (LOWER(social->name[0]) - 'a') + 1;
+
+	UNLINK_SINGLE(social, next_hash, SOCIAL_DATA, social_hash[hash]);
+}
+
+void add_social(SOCIAL_DATA * social)
+{
+	int hash;
+
+	if (!social)
+	{
+		bug("add_social: NULL social", 0);
+		return;
+	}
+
+	if (!social->name)
+	{
+		bug("add_social: NULL social->name", 0);
+		return;
+	}
+
+	if (LOWER(social->name[0]) < 'a' || LOWER(social->name[0]) > 'z')
+		hash = 0;
+	else
+		hash = (LOWER(social->name[0]) - 'a') + 1;
+
+	LINK_LAST(social, next_hash, SOCIAL_DATA, social_hash[hash]);
+
+	return;
 }
diff -ur src/fight.c new/fight.c
--- src/fight.c	Thu Mar 20 17:32:37 2003
+++ new/fight.c	Thu Mar 27 02:17:55 2003
@@ -1809,7 +1809,7 @@
 	extract_char(victim, FALSE);
 	while (victim->first_affect)
 		affect_remove(victim, victim->first_affect);
-	victim->affected_by = race_table[victim->race].aff;
+	victim->affected_by = victim->race->aff;
 	for (i = 0; i < 4; i++)
 		victim->armor[i] = 100;
 	victim->position = POS_RESTING;
diff -ur src/globals.h new/globals.h
--- src/globals.h	Thu Mar 20 17:32:38 2003
+++ new/globals.h	Thu Mar 27 02:17:55 2003
@@ -50,12 +50,15 @@
 #endif
 
 GLOBAL_DEF(struct class_type *class_table, NULL);
-GLOBAL_DEF(struct race_type *race_table, NULL);
+GLOBAL_DEF(RACE_DATA * race_first, NULL);
+GLOBAL_DEF(RACE_DATA * race_last, NULL);
 GLOBAL_DEF(struct skill_type *skill_table, NULL);
 GLOBAL_DEF(struct group_type *group_table, NULL);
 
-GLOBAL_DEF(struct social_type *social_table, NULL);
-GLOBAL_DEF(int maxSocial, 1);
+GLOBAL_DEF(SOCIAL_DATA * social_first, NULL);
+GLOBAL_DEF(SOCIAL_DATA * social_last, NULL);
+
+GLOBAL_DEF(int maxSocial, 0);
 
 GLOBAL_DEF(HELP_DATA * help_first, NULL);
 GLOBAL_DEF(HELP_DATA * help_last, NULL);
@@ -100,18 +103,20 @@
 GLOBAL_DEF(DISABLED_DATA * disabled_last, NULL);	/* interp.c */
 GLOBAL(GQUEST gquest_info);
 GLOBAL(WAR_DATA war_info);
-GLOBAL_DEF(int maxClan, 1);
-GLOBAL_DEF(int maxCommands, 1);
-GLOBAL_DEF(int maxSkill, 1);
-GLOBAL_DEF(int maxGroup, 1);
-GLOBAL_DEF(int maxRace, 1);
-GLOBAL_DEF(int maxClass, 1);
+GLOBAL_DEF(int maxClan, 0);
+GLOBAL_DEF(int maxCommands, 0);
+GLOBAL_DEF(int maxSkill, 0);
+GLOBAL_DEF(int maxGroup, 0);
+GLOBAL_DEF(int maxRace, 0);
+GLOBAL_DEF(int maxClass, 0);
 GLOBAL_DEF(bool fBootDb, FALSE);
 GLOBAL_DEF(int newmobs, 0);
 GLOBAL_DEF(int newobjs, 0);
+#if !defined(NO_STRHASH)
 GLOBAL_DEF(char *string_space, NULL);
 GLOBAL_DEF(int nAllocString, 0);
 GLOBAL_DEF(size_t sAllocString, 0);
+#endif
 GLOBAL_DEF(CHAR_DATA * char_free, NULL);
 GLOBAL_DEF(PC_DATA * pcdata_free, NULL);
 GLOBAL_DEF(DESCRIPTOR_DATA * descriptor_free, NULL);
@@ -119,13 +124,23 @@
 GLOBAL_DEF(AFFECT_DATA * affect_free, NULL);
 GLOBAL_DEF(MBR_DATA * mbr_free, NULL);
 GLOBAL_DEF(int arena, FIGHT_OPEN);
-GLOBAL_DEF(int maxDeity, 1);
-GLOBAL_DEF(struct deity_type *deity_table, NULL);
+GLOBAL_DEF(int maxDeity, 0);
+GLOBAL_DEF(DEITY_DATA * deity_first, NULL);
+GLOBAL_DEF(DEITY_DATA * deity_last, NULL);
 
 GLOBAL_DEF(WPWD_DATA * wpwd_first, NULL);
 GLOBAL_DEF(WPWD_DATA * wpwd_last, NULL);
 
 GLOBAL_DEF(MBR_DATA * mbr_first, NULL);
 GLOBAL_DEF(MBR_DATA * mbr_last, NULL);
+
+GLOBAL_DEF(CLAN_DATA * clan_first, NULL);
+GLOBAL_DEF(CLAN_DATA * clan_last, NULL);
+
+GLOBAL_DEF(CMD_DATA * cmd_first, NULL);
+GLOBAL_DEF(CMD_DATA * cmd_last, NULL);
+
+GLOBAL(CMD_DATA * command_hash[126]);
+GLOBAL(SOCIAL_DATA * social_hash[27]);
 
 #endif
diff -ur src/gquest.c new/gquest.c
--- src/gquest.c	Thu Mar 20 17:32:37 2003
+++ new/gquest.c	Thu Mar 27 02:17:55 2003
@@ -755,7 +755,7 @@
 					 || victim->pIndexData->pShop != NULL)
 				 || victim->pIndexData->vnum < 100
 				 || IS_SET(victim->in_room->room_flags, ROOM_PET_SHOP)
-				 || victim->in_room->clan > -1
+				 || victim->in_room->clan != NULL
 				 || IS_SET(victim->imm_flags, IMM_WEAPON | IMM_MAGIC)
 				 || IS_SET(victim->act,
 						   ACT_TRAIN | ACT_PRACTICE | ACT_IS_HEALER |
diff -ur src/handler.c new/handler.c
--- src/handler.c	Thu Mar 20 17:32:37 2003
+++ new/handler.c	Thu Mar 27 02:17:55 2003
@@ -314,12 +314,12 @@
 
 bool is_clan(CHAR_DATA * ch)
 {
-	return ch->clan > -1;
+	return ch->clan != NULL;
 }
 
 bool is_same_clan(CHAR_DATA * ch, CHAR_DATA * victim)
 {
-	if (clan_table[ch->clan].independent)
+	if (ch->clan->independent || victim->clan->independent)
 		return FALSE;
 	else
 		return (ch->clan == victim->clan);
@@ -841,7 +841,7 @@
 
 	else
 	{
-		max = race_table[ch->race].max_stats[stat] + 4;
+		max = ch->race->max_stats[stat] + 4;
 
 		if (is_prime_stat(ch, stat))
 			max += 2;
@@ -863,7 +863,7 @@
 	if (IS_NPC(ch) || ch->level > LEVEL_IMMORTAL)
 		return 25;
 
-	max = race_table[ch->race].max_stats[stat];
+	max = ch->race->max_stats[stat];
 	if (is_prime_stat(ch, stat))
 	{
 		if (ch->race == race_lookup("human"))
@@ -1951,7 +1951,7 @@
 	/* Death room is set in the clan tabe now */
 	if (!fPull)
 	{
-		ROOM_INDEX_DATA *room = get_room_index(clan_table[ch->clan].hall);
+		ROOM_INDEX_DATA *room = get_room_index(ch->clan->hall);
 		if (room == NULL)
 			room = get_room_index(ROOM_VNUM_ALTAR);
 		char_to_room(ch, room);
@@ -2430,7 +2430,7 @@
 		&& !IS_IMMORTAL(ch))
 		return FALSE;
 
-	if (!IS_IMMORTAL(ch) && pRoomIndex->clan > -1
+	if (!IS_IMMORTAL(ch) && pRoomIndex->clan != NULL
 		&& ch->clan != pRoomIndex->clan)
 		return FALSE;
 
diff -ur src/interp.c new/interp.c
--- src/interp.c	Thu Mar 20 17:32:37 2003
+++ new/interp.c	Thu Mar 27 02:17:55 2003
@@ -50,8 +50,6 @@
 char last_command2[MAX_INPUT_LENGTH];
 DESCRIPTOR_DATA *last_descriptor;
 
-struct cmd_type *cmd_table;
-
 CH_CMD(do_null)
 {
 	chprintln(ch, "This is not a command, notify the immortals.");
@@ -66,7 +64,7 @@
 {
 	char command[MAX_INPUT_LENGTH];
 	char logline[MAX_INPUT_LENGTH];
-	int cmd;
+	CMD_DATA *cmd;
 	int trust;
 	bool found;
 
@@ -128,11 +126,9 @@
 	 */
 	found = FALSE;
 	trust = get_trust(ch);
-	for (cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++)
+	for (cmd = command_hash[LOWER(command[0]) % 126]; cmd; cmd = cmd->next_hash)
 	{
-		if (command[0] == cmd_table[cmd].name[0] &&
-			!str_prefix(command, cmd_table[cmd].name) &&
-			cmd_table[cmd].level <= trust)
+		if (!str_prefix(command, cmd->name) && cmd->level <= trust)
 		{
 			found = TRUE;
 			break;
@@ -142,15 +138,19 @@
 	/*
 	 * Log and snoop.
 	 */
-	if (cmd_table[cmd].log == LOG_NEVER)
-		strcpy(logline, "");
-
-	if ((!IS_NPC(ch) && IS_SET(ch->act, PLR_LOG)) || fLogAll ||
-		cmd_table[cmd].log == LOG_ALWAYS)
+	if (found)
 	{
-		sprintf(log_buf, "Log %s: %s", ch->name, logline);
-		wiznet(log_buf, ch, NULL, WIZ_SECURE, 0, get_trust(ch));
-		log_string(log_buf);
+		if (cmd->log == LOG_NEVER)
+			strcpy(logline, "");
+
+		if ((!IS_NPC(ch) && IS_SET(ch->act, PLR_LOG)) || fLogAll ||
+			cmd->log == LOG_ALWAYS)
+		{
+			sprintf(log_buf, "Log %s: %s", ch->name, logline);
+			wiznet(log_buf, ch, NULL, WIZ_SECURE, 0, get_trust(ch));
+			log_string(log_buf);
+		}
+
 	}
 
 	if (ch->desc != NULL && ch->desc->snoop_by != NULL)
@@ -159,7 +159,6 @@
 		write_to_buffer(ch->desc->snoop_by, logline, 0);
 		write_to_buffer(ch->desc->snoop_by, "\n\r", 2);
 	}
-
 	if (!found)
 	{
 		/*
@@ -169,7 +168,7 @@
 			chprintln(ch, "Huh?");
 		return;
 	}
-	else if (check_disabled(&cmd_table[cmd]))
+	else if (check_disabled(cmd))
 	{
 		chprintln(ch, "This command has been temporarily disabled.");
 		return;
@@ -178,7 +177,7 @@
 	/*
 	 * Character not in position for command?
 	 */
-	if (ch->position < cmd_table[cmd].position)
+	if (ch->position < cmd->position)
 	{
 		switch (ch->position)
 		{
@@ -218,7 +217,7 @@
 	/*
 	 * Dispatch the command.
 	 */
-	(*cmd_table[cmd].do_fun) (ch, argument);
+	(*cmd->do_fun) (ch, argument);
 
 	tail_chain();
 	return;
@@ -239,25 +238,31 @@
 	free_string(command_string);
 }
 
-bool check_social(CHAR_DATA * ch, char *command, const char *argument)
+SOCIAL_DATA *find_social(const char *command)
 {
-	char arg[MAX_INPUT_LENGTH];
-	CHAR_DATA *victim;
-	int cmd;
-	bool found;
+	SOCIAL_DATA *social;
+	int hash;
 
-	found = FALSE;
-	for (cmd = 0; social_table[cmd].name != NULL; cmd++)
+	if (LOWER(command[0]) < 'a' || LOWER(command[0]) > 'z')
+		hash = 0;
+	else
+		hash = (LOWER(command[0]) - 'a') + 1;
+
+	for (social = social_hash[hash]; social; social = social->next_hash)
 	{
-		if (command[0] == social_table[cmd].name[0] &&
-			!str_prefix(command, social_table[cmd].name))
-		{
-			found = TRUE;
-			break;
-		}
+		if (!str_prefix(command, social->name))
+			return social;
 	}
+	return NULL;
+}
 
-	if (!found)
+bool check_social(CHAR_DATA * ch, char *command, const char *argument)
+{
+	char arg[MAX_INPUT_LENGTH];
+	CHAR_DATA *victim;
+	SOCIAL_DATA *cmd;
+
+	if ((cmd = find_social(command)) == NULL)
 		return FALSE;
 
 	if (!IS_NPC(ch) && IS_SET(ch->comm, COMM_NOEMOTE))
@@ -286,7 +291,7 @@
 		 * I just know this is the path to a 12" 'if' statement.  :(
 		 * But two players asked for it already!  -- Furey
 		 */
-		if (!str_cmp(social_table[cmd].name, "snore"))
+		if (!str_cmp(cmd->name, "snore"))
 			break;
 		chprintln(ch, "In your dreams, or what?");
 		return TRUE;
@@ -297,8 +302,8 @@
 	victim = NULL;
 	if (arg[0] == '\0')
 	{
-		act(social_table[cmd].others_no_arg, ch, NULL, victim, TO_ROOM);
-		act(social_table[cmd].char_no_arg, ch, NULL, victim, TO_CHAR);
+		act(cmd->others_no_arg, ch, NULL, victim, TO_ROOM);
+		act(cmd->char_no_arg, ch, NULL, victim, TO_CHAR);
 	}
 	else if ((victim = get_char_room(ch, NULL, arg)) == NULL)
 	{
@@ -306,14 +311,14 @@
 	}
 	else if (victim == ch)
 	{
-		act(social_table[cmd].others_auto, ch, NULL, victim, TO_ROOM);
-		act(social_table[cmd].char_auto, ch, NULL, victim, TO_CHAR);
+		act(cmd->others_auto, ch, NULL, victim, TO_ROOM);
+		act(cmd->char_auto, ch, NULL, victim, TO_CHAR);
 	}
 	else
 	{
-		act(social_table[cmd].others_found, ch, NULL, victim, TO_NOTVICT);
-		act(social_table[cmd].char_found, ch, NULL, victim, TO_CHAR);
-		act(social_table[cmd].vict_found, ch, NULL, victim, TO_VICT);
+		act(cmd->others_found, ch, NULL, victim, TO_NOTVICT);
+		act(cmd->char_found, ch, NULL, victim, TO_CHAR);
+		act(cmd->vict_found, ch, NULL, victim, TO_VICT);
 
 		if (!IS_NPC(ch) && IS_NPC(victim) &&
 			!IS_AFFECTED(victim, AFF_CHARM) && IS_AWAKE(victim) &&
@@ -331,10 +336,9 @@
 			case 6:
 			case 7:
 			case 8:
-				act(social_table[cmd].others_found, victim, NULL,
-					ch, TO_NOTVICT);
-				act(social_table[cmd].char_found, victim, NULL, ch, TO_CHAR);
-				act(social_table[cmd].vict_found, victim, NULL, ch, TO_VICT);
+				act(cmd->others_found, victim, NULL, ch, TO_NOTVICT);
+				act(cmd->char_found, victim, NULL, ch, TO_CHAR);
+				act(cmd->vict_found, victim, NULL, ch, TO_VICT);
 				break;
 
 			case 9:
@@ -449,25 +453,15 @@
  */
 CH_CMD(do_commands)
 {
-	int cmd;
+	CMD_DATA *cmd;
 	int col;
-	struct cmd_type *commands = NULL;
-
-	alloc_mem(commands, struct cmd_type, maxCommands + 1);
-
-	commands =
-		(struct cmd_type *) memcpy(commands, cmd_table,
-								   sizeof(struct cmd_type) * maxCommands + 1);
-
-	qsort(commands, maxCommands, sizeof(cmd_table[0]), srt_cmds_name);
 
 	col = 0;
-	for (cmd = 0; cmd < maxCommands; cmd++)
+	for (cmd = cmd_first; cmd; cmd = cmd->next)
 	{
-		if (commands[cmd].level < LEVEL_HERO &&
-			commands[cmd].level <= get_trust(ch) && commands[cmd].show)
+		if (cmd->level < LEVEL_HERO && cmd->level <= get_trust(ch) && cmd->show)
 		{
-			chprintf(ch, "%-12s", commands[cmd].name);
+			chprintf(ch, "%-12s", cmd->name);
 			if (++col % 6 == 0)
 				chprintln(ch, "");
 		}
@@ -476,30 +470,21 @@
 	if (col % 6 != 0)
 		chprintln(ch, "");
 
-	free_mem(commands);
 	return;
 }
 
 CH_CMD(do_wizhelp)
 {
-	int cmd;
+	CMD_DATA *cmd;
 	int col;
-	struct cmd_type *commands = NULL;
-
-	alloc_mem(commands, struct cmd_type, maxCommands + 1);
-
-	commands =
-		(struct cmd_type *) memcpy(commands, cmd_table,
-								   sizeof(struct cmd_type) * maxCommands + 1);
 
-	qsort(commands, maxCommands, sizeof(cmd_table[0]), srt_cmds_name);
 	col = 0;
-	for (cmd = 0; cmd < maxCommands; cmd++)
+	for (cmd = cmd_first; cmd; cmd = cmd->next)
 	{
-		if (commands[cmd].level >= LEVEL_HERO &&
-			commands[cmd].level <= get_trust(ch) && commands[cmd].show)
+		if (cmd->level >= LEVEL_HERO &&
+			cmd->level <= get_trust(ch) && cmd->show)
 		{
-			chprintf(ch, "%-12s", commands[cmd].name);
+			chprintf(ch, "%-12s", cmd->name);
 			if (++col % 6 == 0)
 				chprintln(ch, "");
 		}
@@ -508,7 +493,6 @@
 	if (col % 6 != 0)
 		chprintln(ch, "");
 
-	free_mem(commands);
 	return;
 }
 
@@ -519,7 +503,7 @@
 
 CH_CMD(do_disable)
 {
-	int i;
+	CMD_DATA *i;
 	DISABLED_DATA *p;
 
 	if (IS_NPC(ch))
@@ -582,19 +566,19 @@
 		}
 
 		/* Search for the command */
-		for (i = 0; cmd_table[i].name[0] != '\0'; i++)
-			if (!str_cmp(cmd_table[i].name, argument))
+		for (i = command_hash[LOWER(argument[0]) % 126]; i; i = i->next_hash)
+			if (!str_cmp(i->name, argument))
 				break;
 
 		/* Found? */
-		if (cmd_table[i].name[0] == '\0')
+		if (!i)
 		{
 			chprintln(ch, "No such command.");
 			return;
 		}
 
 		/* Can the imm use this command at all ? */
-		if (cmd_table[i].level > get_trust(ch))
+		if (i->level > get_trust(ch))
 		{
 			chprintln(ch,
 					  "You don't have access to that command; you cannot disable it.");
@@ -604,7 +588,7 @@
 		/* Disable the command */
 		alloc_mem(p, DISABLED_DATA, 1);
 
-		p->command = &cmd_table[i];
+		p->command = i;
 		p->disabled_by = str_dup(ch->name);	/* save name of disabler */
 		p->level = get_trust(ch);	/* save trust */
 		LINK(p, disabled_first, disabled_last, next, prev);
@@ -635,7 +619,7 @@
 	FILE *fp;
 	DISABLED_DATA *p;
 	char *name;
-	int i;
+	CMD_DATA *i;
 
 	disabled_first = NULL;
 
@@ -649,11 +633,11 @@
 	while (str_cmp(name, END_MARKER))	/* as long as name is NOT END_MARKER :) */
 	{
 		/* Find the command in the table */
-		for (i = 0; cmd_table[i].name[0]; i++)
-			if (!str_cmp(cmd_table[i].name, name))
+		for (i = command_hash[LOWER(name[0]) % 126]; i; i = i->next_hash)
+			if (!str_cmp(i->name, name))
 				break;
 
-		if (!cmd_table[i].name[0])	/* command does not exist? */
+		if (!i)					/* command does not exist? */
 		{
 			bug("Skipping uknown command in " DISABLED_FILE " file.", 0);
 			fread_number(fp);	/* level */
@@ -662,7 +646,7 @@
 		else					/* add new disabled command */
 		{
 			alloc_mem(p, DISABLED_DATA, 1);
-			p->command = &cmd_table[i];
+			p->command = i;
 			p->level = fread_number(fp);
 			p->disabled_by = str_dup(fread_word(fp));
 			LINK(p, disabled_first, disabled_last, next, prev);
diff -ur src/interp.h new/interp.h
--- src/interp.h	Thu Mar 20 17:32:38 2003
+++ new/interp.h	Thu Mar 27 02:17:55 2003
@@ -63,10 +63,9 @@
 	int level;
 	int log;
 	bool show;
+	CMD_DATA *next, *prev, *next_hash;
+	bool valid;
 };
-
-/* the command table itself */
-extern struct cmd_type *cmd_table;
 
 struct dofun_type
 {
diff -ur src/lookup.c new/lookup.c
--- src/lookup.c	Thu Mar 20 17:32:37 2003
+++ new/lookup.c	Thu Mar 27 02:17:55 2003
@@ -50,18 +50,18 @@
 	return NULL;
 }
 
-int clan_lookup(const char *name)
+CLAN_DATA *clan_lookup(const char *name)
 {
-	int clan;
+	CLAN_DATA *clan;
 
-	for (clan = 0; clan < maxClan; clan++)
+	for (clan = clan_first; clan; clan = clan->next)
 	{
-		if (LOWER(name[0]) == LOWER(clan_table[clan].name[0]) &&
-			!str_prefix(name, clan_table[clan].name))
+		if (LOWER(name[0]) == LOWER(clan->name[0]) &&
+			!str_prefix(name, clan->name))
 			return clan;
 	}
 
-	return -1;
+	return NULL;
 }
 
 int position_lookup(const char *name)
@@ -107,18 +107,18 @@
 }
 
 /* returns race number */
-int race_lookup(const char *name)
+RACE_DATA *race_lookup(const char *name)
 {
-	int race;
+	RACE_DATA *race;
 
-	for (race = 0; race_table[race].name != NULL; race++)
+	for (race = race_first; race != NULL; race = race->next)
 	{
-		if (LOWER(name[0]) == LOWER(race_table[race].name[0]) &&
-			!str_prefix(name, race_table[race].name))
+		if (LOWER(name[0]) == LOWER(race->name[0]) &&
+			!str_prefix(name, race->name))
 			return race;
 	}
 
-	return -1;
+	return NULL;
 }
 
 int item_lookup(const char *name)
@@ -171,25 +171,30 @@
 	return NULL;
 }
 
-int command_lookup(const char *name)
+CMD_DATA *command_lookup(const char *name)
 {
-	int i;
+	int hash;
+	CMD_DATA *pCmd;
 
-	for (i = 0; i < maxCommands; i++)
-		if (LOWER(name[0]) == LOWER(cmd_table[i].name[0])
-			&& !str_prefix(name, cmd_table[i].name))
-			return i;
+	if (IS_NULLSTR(name))
+		return NULL;
 
-	return -1;
+	hash = LOWER(name[0]) % 126;
+
+	for (pCmd = command_hash[hash]; pCmd; pCmd = pCmd->next_hash)
+		if (!str_prefix(name, pCmd->name))
+			return pCmd;
+
+	return NULL;
 }
 
-int deity_lookup(const char *arg)
+DEITY_DATA *deity_lookup(const char *arg)
 {
-	int i;
+	DEITY_DATA *i;
 
-	for (i = 0; i < maxDeity; i++)
-		if (!str_prefix(arg, deity_table[i].name))
+	for (i = deity_first; i; i = i->next)
+		if (!str_prefix(arg, i->name))
 			return i;
 
-	return -1;
+	return NULL;
 }
diff -ur src/lookup.h new/lookup.h
--- src/lookup.h	Thu Mar 20 17:32:38 2003
+++ new/lookup.h	Thu Mar 27 02:17:55 2003
@@ -29,11 +29,11 @@
 #if !defined(LOOKUP_H)
 #define LOOKUP_H
 
-int clan_lookup args((const char *name));
+CLAN_DATA *clan_lookup args((const char *name));
 int position_lookup args((const char *name));
 int sex_lookup args((const char *name));
 int size_lookup args((const char *name));
 HELP_DATA *help_lookup args((const char *));
-int deity_lookup args((const char *arg));
+DEITY_DATA *deity_lookup args((const char *arg));
 
 #endif
diff -ur src/mem.c new/mem.c
--- src/mem.c	Thu Mar 20 17:32:37 2003
+++ new/mem.c	Thu Mar 27 02:17:55 2003
@@ -90,14 +90,13 @@
 
 	pArea->next = NULL;
 	pArea->name = str_dup("New area");
-/*    pArea->recall           =   ROOM_VNUM_TEMPLE;      ROM OLC */
-	pArea->area_flags = AREA_ADDED;
-	pArea->security = 1;
+	pArea->area_flags = 0;
+	pArea->security = 9;
 	pArea->builders = str_dup("None");
 	pArea->credits = str_dup("");
 	pArea->min_vnum = 0;
 	pArea->max_vnum = 0;
-	pArea->age = 0;
+	pArea->age = 32;			/* 32 so areas reset on boot */
 	pArea->nplayer = 0;
 	pArea->vnum = top_area;
 	pArea->empty = TRUE;		/* ROM patch */
@@ -168,7 +167,7 @@
 	pRoom->room_flags = 0;
 	pRoom->light = 0;
 	pRoom->sector_type = 0;
-	pRoom->clan = -1;
+	pRoom->clan = NULL;
 	pRoom->heal_rate = 100;
 	pRoom->mana_rate = 100;
 
diff -ur src/merc.h new/merc.h
--- src/merc.h	Thu Mar 20 17:32:38 2003
+++ new/merc.h	Thu Mar 27 02:17:55 2003
@@ -572,6 +572,8 @@
 	const char *name;
 	const char *desc;
 	const char *skillname;
+	DEITY_DATA *next, *prev;
+	bool valid;
 };
 
 struct corpse_data
@@ -600,6 +602,8 @@
 	int stats[MAX_STATS];		/* starting stats */
 	int max_stats[MAX_STATS];	/* maximum stats */
 	int size;					/* aff bits for the race */
+	RACE_DATA *next, *prev;
+	bool valid;
 };
 
 struct spec_type
@@ -1521,7 +1525,7 @@
 	int start_pos;
 	int default_pos;
 	int sex;
-	int race;
+	RACE_DATA *race;
 	long wealth;
 	flag_t form;
 	flag_t parts;
@@ -1569,7 +1573,7 @@
 	bool valid;
 	const char *name;
 	int rank;
-	int clan;
+	CLAN_DATA *clan;
 	int level;
 };
 
@@ -1615,14 +1619,14 @@
 	const char *prompt;
 	const char *prefix;
 	int group;
-	int clan;
+	CLAN_DATA *clan;
 	int sex;
 	int rank;
-	int invited;
+	CLAN_DATA *invited;
 	int Class[MAX_MCLASS];
-	int race;
+	RACE_DATA *race;
 	int level;
-	int deity;
+	DEITY_DATA *deity;
 	int trust;
 	int played;
 	int lines;					/* for the pager */
@@ -1974,7 +1978,7 @@
 	int sector_type;
 	int heal_rate;
 	int mana_rate;
-	int clan;
+	CLAN_DATA *clan;
 };
 
  /* one disabled command */
@@ -2140,6 +2144,28 @@
 } \
 while (0)
 
+#define LINK_LAST(pdata,pnext,type,list) \
+do \
+{ \
+    type *tmp; \
+    if((tmp = list) == NULL) \
+    { \
+		pdata->pnext = list; \
+		list = pdata; \
+        break; \
+    } \
+    for(; tmp; tmp = tmp->pnext) \
+    { \
+        if(!tmp->pnext) \
+        { \
+            tmp->pnext = pdata; \
+            pdata->pnext = NULL; \
+            break; \
+        } \
+    } \
+} \
+while (0)
+
 #define LINK(link, first, last, next, prev)                     	\
 do                                                              	\
 {                                                               	\
@@ -2353,6 +2379,8 @@
 	const char *char_not_found;
 	const char *char_auto;
 	const char *others_auto;
+	SOCIAL_DATA *next, *prev, *next_hash;
+	bool valid;
 };
 
 /*
diff -ur src/multiclass.c new/multiclass.c
--- src/multiclass.c	Thu Mar 20 17:32:37 2003
+++ new/multiclass.c	Thu Mar 27 02:17:55 2003
@@ -164,14 +164,14 @@
 
 			if (!ch->pcdata->stay_race)
 			{
-				int race;
+				RACE_DATA *race;
 
 				chprintln(ch, "The following races are available:");
-				for (race = 0; race_table[race].name != NULL; race++)
+				for (race = race_first; race != NULL; race = race->next)
 				{
-					if (!race_table[race].pc_race)
+					if (!race->pc_race)
 						break;
-					chprint(ch, race_table[race].name);
+					chprint(ch, race->name);
 					chprint(ch, " ");
 				}
 				chprint
@@ -182,7 +182,7 @@
 			{
 				int iClass;
 
-				ch->pcdata->points = race_table[ch->race].points;
+				ch->pcdata->points = ch->race->points;
 
 				sprintf(buf, "Select class number %d [ ",
 						(number_classes(ch) + 1));
@@ -624,7 +624,7 @@
 		return 0;
 
 	for (iClass = 0; ch->Class[iClass] != -1; iClass++)
-		temp = UMIN(temp, race_table[ch->race].class_mult[ch->Class[iClass]]);
+		temp = UMIN(temp, ch->race->class_mult[ch->Class[iClass]]);
 
 	return temp;
 }
@@ -644,11 +644,11 @@
 
 	for (i = 0; i < 5; i++)
 	{
-		if (race_table[ch->race].skills[i] == NULL)
+		if (ch->race->skills[i] == NULL)
 			continue;
-		if (skill_lookup(race_table[ch->race].skills[i]) == sn)
+		if (skill_lookup(ch->race->skills[i]) == sn)
 			return TRUE;
-		if (group_lookup(race_table[ch->race].skills[i]) == sn)
+		if (group_lookup(ch->race->skills[i]) == sn)
 			return TRUE;
 	}
 	return FALSE;
@@ -656,16 +656,16 @@
 
 bool is_deity_skill(CHAR_DATA * ch, int sn)
 {
-	if (ch->deity == -1 || IS_NPC(ch))
+	if (ch->deity == NULL || IS_NPC(ch))
 		return FALSE;
 
-	if (IS_NULLSTR(deity_table[ch->deity].skillname))
+	if (IS_NULLSTR(ch->deity->skillname))
 		return FALSE;
 
-	if (skill_lookup(deity_table[ch->deity].skillname) == sn)
+	if (skill_lookup(ch->deity->skillname) == sn)
 		return TRUE;
 
-	if (group_lookup(deity_table[ch->deity].skillname) == sn)
+	if (group_lookup(ch->deity->skillname) == sn)
 		return TRUE;
 
 	return FALSE;
diff -ur src/music.c new/music.c
--- src/music.c	Thu Mar 20 17:32:37 2003
+++ new/music.c	Thu Mar 27 02:17:55 2003
@@ -208,7 +208,7 @@
 				break;
 			}
 
-			song_table[count].lyrics[lines] = fread_string_eol(fp);
+			song_table[count].lyrics[lines] = str_dup(freadline(fp));
 			lines++;
 		}
 	}
diff -ur src/nanny.c new/nanny.c
--- src/nanny.c	Thu Mar 20 17:32:37 2003
+++ new/nanny.c	Thu Mar 27 02:17:55 2003
@@ -317,7 +317,7 @@
 void handle_con_confirm_new_password(DESCRIPTOR_DATA * d, const char *argument)
 {
 	CHAR_DATA *ch = CH(d);
-	int race;
+	RACE_DATA *race;
 
 	write_to_buffer(d, "\n\r", 2);
 
@@ -330,11 +330,11 @@
 
 	write_to_buffer(d, echo_on_str, 0);
 	write_to_buffer(d, "The following races are available:\n\r  ", 0);
-	for (race = 0; race < maxRace; race++)
+	for (race = race_first; race; race = race->next)
 	{
-		if (!race_table[race].pc_race)
+		if (!race->pc_race)
 			continue;
-		write_to_buffer(d, race_table[race].name, 0);
+		write_to_buffer(d, race->name, 0);
 		write_to_buffer(d, " ", 1);
 	}
 	write_to_buffer(d, "\n\r", 0);
@@ -346,7 +346,8 @@
 {
 	CHAR_DATA *ch = CH(d);
 	char arg[MAX_INPUT_LENGTH];
-	int race, i;
+	RACE_DATA *race;
+	int i;
 
 	one_argument(argument, arg);
 
@@ -364,15 +365,15 @@
 
 	race = race_lookup(argument);
 
-	if (race == -1 || !race_table[race].pc_race)
+	if (race == NULL || !race->pc_race)
 	{
 		write_to_buffer(d, "That is not a valid race.\n\r", 0);
 		write_to_buffer(d, "The following races are available:\n\r  ", 0);
-		for (race = 0; race < maxRace; race++)
+		for (race = race_first; race; race = race->next)
 		{
-			if (!race_table[race].pc_race)
+			if (!race->pc_race)
 				continue;
-			write_to_buffer(d, race_table[race].name, 0);
+			write_to_buffer(d, race->name, 0);
 			write_to_buffer(d, " ", 1);
 		}
 		write_to_buffer(d, "\n\r", 0);
@@ -385,8 +386,7 @@
 	{
 		char buf[MSL];
 
-		sprintf(buf, "You are now a %s forever.\n\r",
-				race_table[ch->race].name);
+		sprintf(buf, "You are now a %s forever.\n\r", ch->race->name);
 		write_to_buffer(d, buf, 0);
 		ch->pcdata->stay_race = TRUE;
 	}
@@ -394,24 +394,24 @@
 	ch->race = race;
 	/* initialize stats */
 	for (i = 0; i < MAX_STATS; i++)
-		ch->perm_stat[i] = race_table[race].stats[i];
-	ch->affected_by = ch->affected_by | race_table[race].aff;
-	ch->imm_flags = ch->imm_flags | race_table[race].imm;
-	ch->res_flags = ch->res_flags | race_table[race].res;
-	ch->vuln_flags = ch->vuln_flags | race_table[race].vuln;
-	ch->form = race_table[race].form;
-	ch->parts = race_table[race].parts;
+		ch->perm_stat[i] = race->stats[i];
+	ch->affected_by = ch->affected_by | race->aff;
+	ch->imm_flags = ch->imm_flags | race->imm;
+	ch->res_flags = ch->res_flags | race->res;
+	ch->vuln_flags = ch->vuln_flags | race->vuln;
+	ch->form = race->form;
+	ch->parts = race->parts;
 
 	/* add skills */
 	for (i = 0; i < 5; i++)
 	{
-		if (race_table[race].skills[i] == NULL)
+		if (race->skills[i] == NULL)
 			break;
-		group_add(ch, race_table[race].skills[i], FALSE);
+		group_add(ch, race->skills[i], FALSE);
 	}
 	/* add cost */
-	ch->pcdata->points = race_table[race].points;
-	ch->size = race_table[race].size;
+	ch->pcdata->points = race->points;
+	ch->size = race->size;
 
 	write_to_buffer(d, "What is your sex (M/F)? ", 0);
 	d->connected = CON_GET_NEW_SEX;
@@ -513,14 +513,13 @@
 
 void send_deity_info(DESCRIPTOR_DATA * d)
 {
-	int i;
+	DEITY_DATA *i;
 	char buf[MSL];
 
 	write_to_buffer(d, "\n\rDeities Available:\n\r", 0);
-	for (i = 0; i < maxDeity; i++)
+	for (i = deity_first; i; i = i->next)
 	{
-		sprintf(buf, "\t%-12s : %s\n\r", deity_table[i].name,
-				deity_table[i].desc);
+		sprintf(buf, "\t%-12s : %s\n\r", i->name, i->desc);
 		write_to_buffer(d, buf, 0);
 	}
 	write_to_buffer(d, "\n\r", 2);
@@ -559,7 +558,7 @@
 void handle_con_get_deity(DESCRIPTOR_DATA * d, const char *argument)
 {
 	char arg[MIL];
-	int i;
+	DEITY_DATA *i;
 	CHAR_DATA *ch = CH(d);
 	char buf[MSL];
 
@@ -580,14 +579,14 @@
 	}
 	i = deity_lookup(argument);
 
-	if (i == -1)
+	if (i == NULL)
 	{
 		send_deity_info(d);
 		write_to_buffer(d, "What deity would you like to worship?\n\r", 0);
 		return;
 	}
 	ch->deity = i;
-	sprintf(buf, "\n\rYou now worship %s.\n\r", deity_table[ch->deity].name);
+	sprintf(buf, "\n\rYou now worship %s.\n\r", ch->deity->name);
 	write_to_buffer(d, buf, 0);
 	write_to_buffer(d, "\n\r", 0);
 
@@ -704,18 +703,18 @@
 
 	if (!str_cmp(argument, "done"))
 	{
-		if (ch->pcdata->points == race_table[ch->race].points)
+		if (ch->pcdata->points == ch->race->points)
 		{
 			chprintln(ch, "You didn't pick anything.");
 			return;
 		}
 
 		if (!IS_SET(ch->act, PLR_REMORT)
-			&& ch->pcdata->points <= 40 + race_table[ch->race].points)
+			&& ch->pcdata->points < 40 + ch->race->points)
 		{
 			chprintlnf(ch,
 					   "You must take at least %d points of skills and groups",
-					   40 + race_table[ch->race].points);
+					   40 + ch->race->points);
 			return;
 		}
 
diff -ur src/olc.c new/olc.c
--- src/olc.c	Thu Mar 20 17:32:38 2003
+++ new/olc.c	Thu Mar 27 02:17:55 2003
@@ -668,7 +668,6 @@
 	{"delete", NULL, olced_olded, (const void *) cedit_delete},
 	{"create", NULL, olced_olded, (const void *) cedit_create},
 	{"rank", NULL, olced_olded, (const void *) cedit_rank},
-	{"rshort", NULL, olced_olded, (const void *) cedit_rshort},
 	{"commands", NULL, olced_olded, (const void *) show_commands},
 	{"?", NULL, olced_olded, (const void *) show_help},
 	{"version", NULL, olced_olded, (const void *) show_version},
@@ -677,7 +676,7 @@
 
 const struct olc_comm_type social_olc_comm_table[] = {
 	{"show", NULL, olced_olded, (const void *) sedit_show},
-	{"name", (void *) &xSoc.name, olced_str, NULL},
+	{"name", NULL, olced_olded, (const void *) sedit_name},
 	{"create", NULL, olced_olded, (const void *) sedit_create},
 	{"delete", NULL, olced_olded, (const void *) sedit_delete},
 	{"cnoarg", (void *) &xSoc.char_no_arg, olced_str, NULL},
@@ -696,7 +695,7 @@
 const struct olc_comm_type cmd_olc_comm_table[] = {
 	{"show", NULL, olced_olded, (const void *) cmdedit_show},
 	{"create", NULL, olced_olded, (const void *) cmdedit_create},
-	{"name", (void *) &xCmd.name, olced_str, NULL},
+	{"name", NULL, olced_olded, (const void *) cmdedit_name},
 	{"rearrange", NULL, olced_olded, (void *) cmdedit_rearrange},
 
 	{"level", (void *) &xCmd.level, olced_number,
@@ -1490,23 +1489,6 @@
 	return;
 }
 
-CLAN_DATA *get_clan_data(int clan)
-{
-	if (clan < maxClan)
-		return &clan_table[clan];
-
-	return &clan_table[0];
-
-}
-
-CMD_DATA *get_cmd_data(int cmd)
-{
-	if (cmd > -1 && cmd < maxCommands)
-		return &cmd_table[cmd];
-
-	return &cmd_table[0];
-}
-
 SKILL_DATA *get_skill_data(int skill)
 {
 	if (skill > -1 && skill < maxSkill)
@@ -1523,14 +1505,6 @@
 	return &group_table[0];
 }
 
-RACE_DATA *get_race_data(int race)
-{
-	if (race < maxRace && race > -1)
-		return &race_table[race];
-
-	return &race_table[0];
-}
-
 CLASS_DATA *get_class_data(int Class)
 {
 	if (Class > -1 && Class < maxClass)
@@ -1907,37 +1881,27 @@
 CH_CMD(do_cedit)
 {
 	CLAN_DATA *pClan;
-	int value;
 	char arg[MSL];
 
 	if (IS_NPC(ch))
 		return;
 
-	pClan = &clan_table[0];
+	pClan = clan_first;
 
 	argument = one_argument(argument, arg);
 
 	if (IS_NULLSTR(arg))
 	{
-		chprintln(ch, "Syntax: cedit create\n\r        cedit #/clan name");
+		chprintln(ch, "Syntax: cedit create\n\r        cedit <clan name>");
 		return;
 	}
 
-	if (is_number(arg))
-		value = atoi(arg);
-	else
-		value = clan_lookup(arg);
+	pClan = clan_lookup(arg);
 
-	if (value > -1)
+	if (!pClan || IS_NULLSTR(pClan->name))
 	{
-		pClan = get_clan_data(value);
-
-		if (!pClan || IS_NULLSTR(pClan->name))
-		{
-			chprintln(ch, "That clan does not exist.");
-			return;
-		}
-
+		chprintln(ch, "That clan does not exist.");
+		return;
 	}
 	else if (!str_cmp(arg, "save"))
 	{
@@ -1964,38 +1928,26 @@
 CH_CMD(do_cmdedit)
 {
 	CMD_DATA *pCmd;
-	int value;
 	char arg[MSL];
 
 	if (IS_NPC(ch))
 		return;
 
-	pCmd = &cmd_table[0];
-
 	argument = one_argument(argument, arg);
 
 	if (IS_NULLSTR(arg))
 	{
 		chprintln(ch, "Syntax: cmdedit create\n\r"
-				  "        cmdedit #/command name");
+				  "        cmdedit <command name>");
 		return;
 	}
 
-	if (is_number(arg))
-		value = atoi(arg);
-	else
-		value = command_lookup(arg);
+	pCmd = command_lookup(arg);
 
-	if (value > -1)
+	if (!pCmd || IS_NULLSTR(pCmd->name))
 	{
-		pCmd = get_cmd_data(value);
-
-		if (!pCmd || IS_NULLSTR(pCmd->name))
-		{
-			chprintln(ch, "That command does not exist.");
-			return;
-		}
-
+		chprintln(ch, "That command does not exist.");
+		return;
 	}
 	else if (!str_cmp(arg, "save"))
 	{
@@ -2144,37 +2096,27 @@
 CH_CMD(do_raedit)
 {
 	RACE_DATA *pRace;
-	int value;
 	char arg[MSL];
 
 	if (IS_NPC(ch))
 		return;
 
-	pRace = &race_table[0];
+	pRace = race_first;
 
 	argument = one_argument(argument, arg);
 
 	if (IS_NULLSTR(arg))
 	{
-		chprintln(ch, "Syntax: raedit create\n\r        raedit #/race name");
+		chprintln(ch, "Syntax: raedit create\n\r        raedit <race name>");
 		return;
 	}
 
-	if (is_number(arg))
-		value = atoi(arg);
-	else
-		value = race_lookup(arg);
+	pRace = race_lookup(arg);
 
-	if (value > 0)
+	if (!pRace || IS_NULLSTR(pRace->name))
 	{
-		pRace = get_race_data(value);
-
-		if (!pRace || IS_NULLSTR(pRace->name))
-		{
-			chprintln(ch, "That race does not exist.");
-			return;
-		}
-
+		chprintln(ch, "That race does not exist.");
+		return;
 	}
 	else if (!str_cmp(arg, "save"))
 	{
diff -ur src/olc.h new/olc.h
--- src/olc.h	Thu Mar 20 17:32:38 2003
+++ new/olc.h	Thu Mar 27 02:17:55 2003
@@ -324,13 +324,13 @@
 DECLARE_OLC_FUN(cedit_create);
 DECLARE_OLC_FUN(cedit_delete);
 DECLARE_OLC_FUN(cedit_rank);
-DECLARE_OLC_FUN(cedit_rshort);
 
 DECLARE_OLC_FUN(cmdedit_show);
 DECLARE_OLC_FUN(cmdedit_create);
 DECLARE_OLC_FUN(cmdedit_delete);
 DECLARE_OLC_FUN(cmdedit_dofun);
 DECLARE_OLC_FUN(cmdedit_rearrange);
+DECLARE_OLC_FUN(cmdedit_name);
 
 DECLARE_OLC_FUN(gredit_show);
 DECLARE_OLC_FUN(gredit_create);
@@ -421,7 +421,6 @@
 void free_pcode args((PROG_CODE * pCode));
 
 void sedit args((CHAR_DATA * ch, char *argument));
-SOCIAL_DATA *get_social_data args((const char *name));
 
 void autoset args((MOB_INDEX_DATA * pMob));
 void autohard args((MOB_INDEX_DATA * pMob));
diff -ur src/olc_act.c new/olc_act.c
--- src/olc_act.c	Thu Mar 20 17:32:38 2003
+++ new/olc_act.c	Thu Mar 27 02:17:55 2003
@@ -820,8 +820,9 @@
 
 #if 0							/* ROM OLC */
 	chprintlnf(ch, "Recall:   [%5d] %s", pArea->recall,
-			   get_room_index(pArea->recall) ? get_room_index(pArea->recall)->
-			   name : "none");
+			   get_room_index(pArea->recall) ? get_room_index(pArea->
+															  recall)->name :
+			   "none");
 #endif							/* ROM */
 
 	chprintlnf(ch, "File:     %s", pArea->file_name);
@@ -863,6 +864,7 @@
 
 	pArea = new_area();
 	LINK(pArea, area_first, area_last, next, prev);
+	top_area++;
 	edit_start(ch, pArea, ED_AREA);
 	SET_BIT(pArea->area_flags, AREA_ADDED);
 	chprintln(ch, "Area Created.");
@@ -1152,10 +1154,9 @@
 		strcat(buf1, buf);
 	}
 
-	if (pRoom->clan > -1)
+	if (pRoom->clan != NULL)
 	{
-		sprintf(buf, "Clan      : [%d] %s\n\r", pRoom->clan,
-				clan_table[pRoom->clan].name);
+		sprintf(buf, "Clan      : %s\n\r", pRoom->clan->name);
 		strcat(buf1, buf);
 	}
 
@@ -2067,8 +2068,9 @@
 				   "[v4] Weight Mult [%ld]", obj->value[0],
 				   flag_string(container_flags, obj->value[1]),
 				   get_obj_index(obj->value[2]) ? get_obj_index(obj->value
-																[2])->short_descr
-				   : "none", obj->value[2], obj->value[3], obj->value[4]);
+																[2])->
+				   short_descr : "none", obj->value[2], obj->value[3],
+				   obj->value[4]);
 		break;
 
 	case ITEM_DRINK_CON:
@@ -2915,7 +2917,7 @@
 			   pMob->vnum,
 			   pMob->sex == SEX_MALE ? "male   " : pMob->sex ==
 			   SEX_FEMALE ? "female " : pMob->sex ==
-			   3 ? "random " : "neutral", race_table[pMob->race].name);
+			   3 ? "random " : "neutral", pMob->race->name);
 
 	chprintlnf(ch,
 			   "Level:       [%2d]    Align: [%4d]      Hitroll: [%2d] Dam Type:    [%s]",
@@ -4099,19 +4101,19 @@
 ED_FUN_DEC(olced_race)
 {
 	MOB_INDEX_DATA *pMob = (MOB_INDEX_DATA *) arg;
-	int race;
+	RACE_DATA *race;
 
-	if (!IS_NULLSTR(argument) && (race = race_lookup(argument)) != -1)
+	if (!IS_NULLSTR(argument) && (race = race_lookup(argument)) != NULL)
 	{
 		pMob->race = race;
-		pMob->act |= race_table[race].act;
-		pMob->affected_by |= race_table[race].aff;
-		pMob->off_flags |= race_table[race].off;
-		pMob->imm_flags |= race_table[race].imm;
-		pMob->res_flags |= race_table[race].res;
-		pMob->vuln_flags |= race_table[race].vuln;
-		pMob->form |= race_table[race].form;
-		pMob->parts |= race_table[race].parts;
+		pMob->act |= race->act;
+		pMob->affected_by |= race->aff;
+		pMob->off_flags |= race->off;
+		pMob->imm_flags |= race->imm;
+		pMob->res_flags |= race->res;
+		pMob->vuln_flags |= race->vuln;
+		pMob->form |= race->form;
+		pMob->parts |= race->parts;
 
 		chprintln(ch, "Race set.");
 		return TRUE;
@@ -4119,14 +4121,16 @@
 
 	if (argument[0] == '?')
 	{
+		int i = 0;
 
 		chprintln(ch, "Available races are:");
 
-		for (race = 0; race_table[race].name != NULL; race++)
+		for (race = race_first; race != NULL; race = race->next)
 		{
-			if ((race % 3) == 0)
+			if ((i % 3) == 0)
 				chprintln(ch, "");
-			chprintf(ch, " %-15s", race_table[race].name);
+			chprintf(ch, " %-15s", race->name);
+			i++;
 		}
 
 		chprintln(ch, "");
@@ -4472,39 +4476,10 @@
 	chprintf(ch, "Hall: %ld\n\r", pClan->hall);
 	chprintf(ch, "Independant: %s\n\r", pClan->independent ? "TRUE" : "FALSE");
 	for (r = 0; r < MAX_RANK; r++)
-		chprintf(ch, "Rank %d: %s [%s]\n\r", r + 1, pClan->rank[r].rankname,
-				 pClan->rank[r].shortname);
+		chprintf(ch, "Rank %d: %s\n\r", r + 1, pClan->rank[r].rankname);
 	return TRUE;
 }
 
-CEDIT(cedit_rshort)
-{
-	CLAN_DATA *pClan;
-	char arg1[MIL];
-
-	EDIT_CLAN(ch, pClan);
-
-	argument = one_argument(argument, arg1);
-
-	if (is_number(arg1) && atoi(arg1) <= MAX_RANK && atoi(arg1) > 0)
-	{
-		int value;
-
-		value = atoi(arg1) - 1;
-
-		if (!IS_NULLSTR(argument) && strlen_color(argument) == 3)
-		{
-			replace_string(pClan->rank[value].shortname, argument);
-			chprintln(ch, "Rank short name changed.");
-			return TRUE;
-		}
-
-	}
-
-	chprintln(ch, "Syntax: rshort rank# newname (3 letters only minus color)");
-	return FALSE;
-}
-
 CEDIT(cedit_rank)
 {
 	CLAN_DATA *pClan;
@@ -4535,42 +4510,19 @@
 
 CEDIT(cedit_create)
 {
-	int j, i = maxClan, x;
 	CLAN_DATA *pClan;
-	struct clan_type *new_table;
 	char buf[MIL];
 
-	if (!IS_NULLSTR(argument) && clan_lookup(argument) == -1)
+	if (!IS_NULLSTR(argument) && clan_lookup(argument) == NULL)
 		sprintf(buf, argument);
 	else
 		sprintf(buf, "New Clan%d", maxClan + 1);
 
-	maxClan++;
-
-	alloc_mem(new_table, struct clan_type, maxClan);
+	pClan = new_clan();
+	replace_string(pClan->name, buf);
+	replace_string(pClan->who_name, buf);
+	LINK(pClan, clan_first, clan_last, next, prev);
 
-	if (!new_table)
-	{
-		chprintln(ch, "Memory Allocation Failed!!! Unable to create clan.");
-		return FALSE;
-	}
-
-	for (j = 0; j < i; j++)
-		new_table[j] = clan_table[j];
-
-	free_mem(clan_table);
-	clan_table = new_table;
-
-	clan_table[i].name = str_dup(buf);
-	clan_table[i].who_name = str_dup(buf);
-
-	for (x = 0; x < MAX_RANK; x++)
-	{
-		clan_table[i].rank[x].shortname = str_dup("---");
-		clan_table[i].rank[x].rankname = str_dup("Member");
-	}
-
-	pClan = &clan_table[i];
 	edit_start(ch, pClan, ED_CLAN);
 	chprintln(ch, "Clan created.");
 	return TRUE;
@@ -4590,74 +4542,47 @@
 		return FALSE;
 	}
 	else
-
 	{
-		int i, j = 0, c;
-		struct clan_type *new_table;
 		CHAR_DATA *pch;
-		int nMatch = 0;
+		int hash;
 		ROOM_INDEX_DATA *pRoom;
-		vnum_t vnum;
 		MBR_DATA *pmbr, *next = NULL;
 
-		alloc_mem(new_table, struct clan_type, maxClan);
-
-		if (!new_table)
-		{
-			chprintln(ch, "Memory Allocation error!!! Unable to delete clan.");
-			return FALSE;
-		}
-
-		c = clan_lookup(pClan->name);
-
 		for (pmbr = mbr_first; pmbr != NULL; pmbr = next)
 		{
 			next = pmbr->next;
 
-			if (pmbr->clan == c)
+			if (pmbr->clan == pClan)
 			{
 				UNLINK(pmbr, mbr_first, mbr_last, next, prev);
 				free_mbr(pmbr);
 			}
-			else if (pmbr->clan > c)
-				pmbr->clan -= 1;
 		}
 
 		for (pch = char_first; pch != NULL; pch = pch->next)
 		{
-			if (pch->clan == c)
-				pch->clan = -1;
-			else if (pch->clan > c)
-				pch->clan -= 1;
+			if (pch->clan == pClan)
+			{
+				pch->clan = NULL;
+				pch->rank = 0;
+			}
 		}
 
-		for (vnum = 0; nMatch < top_room; vnum++)
+		for (hash = 0; hash < MAX_KEY_HASH; hash++)
 		{
-			if ((pRoom = get_room_index(vnum)) != NULL)
+			for (pRoom = room_index_hash[hash]; pRoom; pRoom = pRoom->next)
 			{
-				nMatch++;
-				if (pRoom->clan == c)
+				if (pRoom->clan == pClan)
 				{
-					pRoom->clan = -1;
-					SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
-				}
-				else if (pRoom->clan > c)
-				{
-					pRoom->clan -= 1;
+					pRoom->clan = NULL;
 					SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
 				}
 			}
 		}
 
-		for (i = 0; i < maxClan; i++)
-			if (i != c)
-				new_table[j++] = clan_table[i];
-
-		free_mem(clan_table);
-		clan_table = new_table;
-		maxClan--;
-
-		pClan = &clan_table[0];
+		UNLINK(pClan, clan_first, clan_last, next, prev);
+		free_clan(pClan);
+		pClan = clan_first;
 		edit_start(ch, pClan, ED_CLAN);
 		chprintln(ch, "Clan deleted.");
 	}
diff -ur src/olc_class.c new/olc_class.c
--- src/olc_class.c	Thu Mar 20 17:32:38 2003
+++ new/olc_class.c	Thu Mar 27 02:17:55 2003
@@ -45,6 +45,7 @@
 	int x = 0;
 	CLASS_DATA *pClass;
 	struct class_type *new_table;
+	RACE_DATA *race;
 	char buf[MIL];
 
 	if (!IS_NULLSTR(argument) && class_lookup(argument) == -1)
@@ -73,10 +74,10 @@
 		skill_table[x].skill_level[i] = ANGEL;
 	}
 
-	for (x = 0; x < maxRace; x++)
+	for (race = race_first; race; race = race->next)
 	{
-		realloc_mem(race_table[x].class_mult, int, maxClass);
-		race_table[x].class_mult[i] = 100;
+		realloc_mem(race->class_mult, int, maxClass);
+		race->class_mult[i] = 100;
 	}
 
 	for (x = 0; x < maxGroup; x++)
@@ -113,6 +114,7 @@
 	{
 		int i, j = 0, c;
 		struct class_type *new_table;
+		RACE_DATA *race;
 		CHAR_DATA *pch;
 		int iClass;
 		bool invalid;
@@ -163,8 +165,8 @@
 		for (i = 0; i < maxGroup; i++)
 			realloc_mem(group_table[i].rating, int, maxClass);
 
-		for (i = 0; i < maxRace; i++)
-			realloc_mem(race_table[i].class_mult, int, maxClass);
+		for (race = race_first; race; race = race->next)
+			realloc_mem(race->class_mult, int, maxClass);
 
 		pClass = &class_table[0];
 		edit_start(ch, pClass, ED_CLASS);
diff -ur src/olc_cmd.c new/olc_cmd.c
--- src/olc_cmd.c	Thu Mar 20 17:32:38 2003
+++ new/olc_cmd.c	Thu Mar 27 02:17:55 2003
@@ -35,6 +35,7 @@
 #include "interp.h"
 #include "olc.h"
 #include "tables.h"
+#include "recycle.h"
 
 const char *do_fun_name args((DO_FUN * fun));
 DO_FUN *do_fun_lookup args((const char *name));
@@ -43,7 +44,7 @@
 
 CH_CMD(do_cmdcheck)
 {
-	int i;
+	CMD_DATA *i;
 	DO_FUN *fun;
 	bool found = FALSE;
 
@@ -52,12 +53,12 @@
 	else if (!str_prefix(argument, "null"))
 	{
 		chprintln(ch, "NULL commands:");
-		for (i = 0; i < maxCommands; i++)
+		for (i = cmd_first; i; i = i->next)
 		{
-			if (cmd_table[i].do_fun == do_null)
+			if (i->do_fun == do_null)
 			{
 				found = TRUE;
-				chprintlnf(ch, "%s", cmd_table[i].name);
+				chprintlnf(ch, "%s", i->name);
 			}
 		}
 		if (!found)
@@ -65,16 +66,18 @@
 	}
 	else if (!str_prefix(argument, "missing"))
 	{
-		int cmd, pos = 0;
+		CMD_DATA *cmd;
+		int j;
+		int pos = 0;
 		bool any = FALSE;
 
 		chprintln(ch, "Functions missing command entries:");
-		for (i = 0; dofun_table[i].fun != NULL; i++)
+		for (j = 0; dofun_table[j].fun != NULL; i++)
 		{
 			found = FALSE;
-			for (cmd = 0; cmd < maxCommands; cmd++)
+			for (cmd = cmd_first; cmd; cmd = cmd->next)
 			{
-				if (dofun_table[i].fun == cmd_table[cmd].do_fun)
+				if (dofun_table[j].fun == cmd->do_fun)
 				{
 					found = TRUE;
 					break;
@@ -83,7 +86,7 @@
 			if (!found)
 			{
 				any = TRUE;
-				chprintf(ch, "%15s ", dofun_table[i].name);
+				chprintf(ch, "%15s ", dofun_table[j].name);
 				if (++pos % 4 == 0)
 					chprintln(ch, "");
 			}
@@ -96,12 +99,12 @@
 	else if ((fun = do_fun_lookup(argument)) != NULL)
 	{
 		chprintlnf(ch, "%s commands:", argument);
-		for (i = 0; i < maxCommands; i++)
+		for (i = cmd_first; i; i = i->next)
 		{
-			if (cmd_table[i].do_fun == fun)
+			if (i->do_fun == fun)
 			{
 				found = TRUE;
-				chprintlnf(ch, "%s", cmd_table[i].name);
+				chprintlnf(ch, "%s", i->name);
 			}
 		}
 		if (!found)
@@ -130,42 +133,19 @@
 
 CMDEDIT(cmdedit_create)
 {
-	int j, i = maxCommands;
 	CMD_DATA *pCmd;
-	struct cmd_type *new_table;
 	char buf[MIL];
 
-	if (!IS_NULLSTR(argument) && command_lookup(argument) == -1)
+	if (!IS_NULLSTR(argument) && command_lookup(argument) == NULL)
 		sprintf(buf, argument);
 	else
 		sprintf(buf, "New Command%d", maxCommands + 1);
 
-	maxCommands++;
+	pCmd = new_command();
+	replace_string(pCmd->name, buf);
+	add_command(pCmd);
+	LINK(pCmd, cmd_first, cmd_last, next, prev);
 
-	alloc_mem(new_table, struct cmd_type, maxCommands + 1);
-
-	if (!new_table)
-	{
-		chprintln(ch, "Memory Allocation Failed!!! Unable to create command.");
-		return FALSE;
-	}
-
-	for (j = 0; j < i; j++)
-		new_table[j] = cmd_table[j];
-
-	free_mem(cmd_table);
-	cmd_table = new_table;
-
-	cmd_table[i].name = str_dup(buf);
-	cmd_table[i].do_fun = do_null;
-	cmd_table[i].level = 0;
-	cmd_table[i].position = POS_DEAD;
-	cmd_table[i].show = TRUE;
-	cmd_table[i].log = LOG_NORMAL;
-
-	cmd_table[i + 1].name = str_dup("");
-
-	pCmd = &cmd_table[i];
 	edit_start(ch, pCmd, ED_CMD);
 	chprintln(ch, "Command created.");
 	return TRUE;
@@ -219,29 +199,9 @@
 	else
 
 	{
-		int i, j = 0, c;
-		struct cmd_type *new_table;
-
-		alloc_mem(new_table, struct cmd_type, maxCommands + 1);
-
-		if (!new_table)
-		{
-			chprintln
-				(ch, "Memory Allocation error!!! Unable to delete command.");
-			return FALSE;
-		}
-
-		c = command_lookup(pCmd->name);
-
-		for (i = 0; i < maxCommands; i++)
-			if (i != c)
-				new_table[j++] = cmd_table[i];
-
-		free_mem(cmd_table);
-		cmd_table = new_table;
-		maxCommands--;
-
-		pCmd = &cmd_table[0];
+		UNLINK(pCmd, cmd_first, cmd_last, next, prev);
+		free_command(pCmd);
+		pCmd = cmd_first;
 		edit_start(ch, pCmd, ED_CMD);
 		chprintln(ch, "Command deleted.");
 	}
@@ -251,10 +211,7 @@
 
 CMDEDIT(cmdedit_rearrange)
 {
-	CMD_DATA *pCmd;
-	int x;
-	int i, c;
-	CMD_DATA *new_table;
+	CMD_DATA *pCmd, *iCmd, *tmp;
 	bool found = FALSE;
 
 	EDIT_CMD(ch, pCmd);
@@ -265,56 +222,76 @@
 		return FALSE;
 	}
 
-	if ((x = command_lookup(argument)) == -1)
+	if ((iCmd = command_lookup(argument)) == NULL)
 	{
 		chprintln(ch, "That is not a command.");
 		return FALSE;
 	}
 
-	c = command_lookup(pCmd->name);
-
-	if (x == c)
+	if (iCmd == pCmd)
 	{
 		chprintln(ch, "Can't rearrange the same command.");
 		return FALSE;
 	}
 
-	if (c < x)
-	{
-		chprintlnf(ch, "Error: command %s is already above %s.",
-				   cmd_table[c].name, cmd_table[x].name);
-		return FALSE;
-	}
-
-	alloc_mem(new_table, struct cmd_type, maxCommands);
-
-	if (!new_table)
-	{
-		chprintln(ch, "Memory Allocation error!!! Unable to delete command.");
-		return FALSE;
-	}
-
-	for (i = 0; i < maxCommands; i++)
+	for (tmp = cmd_first; tmp; tmp = tmp->next)
 	{
-		if (found)
+		if (tmp == pCmd)
 		{
-			new_table[i] = cmd_table[i - 1];
+			found = TRUE;
 			continue;
 		}
-		if (i + 1 == x)
+		if (tmp == iCmd)
 		{
-			new_table[i] = cmd_table[c];
-			i++;
-			new_table[i] = cmd_table[i - 1];
-			found = TRUE;
-			continue;
+			if (found)
+			{
+				chprintlnf(ch, "Error: command %s is already above %s.",
+						   pCmd->name, iCmd->name);
+				return FALSE;
+			}
+			else
+				break;
 		}
-		new_table[i] = cmd_table[i];
 	}
-	free_mem(cmd_table);
-	cmd_table = new_table;
+
+	UNLINK(pCmd, cmd_first, cmd_last, next, prev);
+	INSERT(pCmd, iCmd, cmd_first, next, prev);
+
+	for (tmp = cmd_first; tmp; tmp = tmp->next)
+		unlink_command(tmp);
+	for (tmp = cmd_first; tmp; tmp = tmp->next)
+		add_command(tmp);
 
 	chprintln(ch, "Command moved.");
 
+	return TRUE;
+}
+
+CMDEDIT(cmdedit_name)
+{
+	bool relocate;
+	CMD_DATA *pCmd;
+	char arg1[MIL];
+
+	EDIT_CMD(ch, pCmd);
+
+	one_argument(argument, arg1);
+	if (IS_NULLSTR(arg1))
+	{
+		chprintln(ch, "Cannot clear name field!");
+		return FALSE;
+	}
+	if (arg1[0] != pCmd->name[0])
+	{
+		unlink_command(pCmd);
+		relocate = TRUE;
+	}
+	else
+		relocate = FALSE;
+
+	replace_string(pCmd->name, arg1);
+	if (relocate)
+		add_command(pCmd);
+	chprintln(ch, "Name set.");
 	return TRUE;
 }
diff -ur src/olc_deity.c new/olc_deity.c
--- src/olc_deity.c	Thu Mar 20 17:32:38 2003
+++ new/olc_deity.c	Thu Mar 27 02:17:55 2003
@@ -36,16 +36,10 @@
 #include "recycle.h"
 #include "globals.h"
 #include "tables.h"
+#include "recycle.h"
 
 #define DEDIT(fun)  bool fun(CHAR_DATA *ch, const char *argument)
 
-DEITY_DATA *get_deity_data(int deity)
-{
-	if (deity > -1 && deity < maxDeity)
-		return &deity_table[deity];
-
-	return &deity_table[0];
-}
 void dedit(CHAR_DATA * ch, char *argument)
 {
 	if (get_trust(ch) < MAX_LEVEL - 5)
@@ -75,37 +69,27 @@
 CH_CMD(do_dedit)
 {
 	DEITY_DATA *pDeity;
-	int value;
 	char arg[MSL];
 
 	if (IS_NPC(ch))
 		return;
 
-	pDeity = &deity_table[0];
+	pDeity = deity_first;
 
 	argument = one_argument(argument, arg);
 
 	if (IS_NULLSTR(arg))
 	{
-		chprintln(ch, "Syntax: dedit create\n\r        dedit #/deity name");
+		chprintln(ch, "Syntax: dedit create\n\r        dedit <deity name>");
 		return;
 	}
 
-	if (is_number(arg))
-		value = atoi(arg);
-	else
-		value = deity_lookup(arg);
+	pDeity = deity_lookup(arg);
 
-	if (value > -1)
+	if (!pDeity || IS_NULLSTR(pDeity->name))
 	{
-		pDeity = get_deity_data(value);
-
-		if (!pDeity || IS_NULLSTR(pDeity->name))
-		{
-			chprintln(ch, "That deity does not exist.");
-			return;
-		}
-
+		chprintln(ch, "That deity does not exist.");
+		return;
 	}
 	else if (!str_cmp(arg, "save"))
 	{
@@ -147,14 +131,13 @@
 
 DEDIT(dedit_list)
 {
-	int i;
+	DEITY_DATA *i;
 	bool found = FALSE;
 
-	for (i = 0; i < maxDeity; i++)
+	for (i = deity_first; i; i = i->next)
 	{
 		found = TRUE;
-		chprintlnf(ch, "\t%-12s : %s", deity_table[i].name,
-				   IS_STRSET(deity_table[i].desc));
+		chprintlnf(ch, "\t%-12s : %s", i->name, IS_STRSET(i->desc));
 	}
 	if (!found)
 		chprintln(ch, "No deities.");
@@ -163,37 +146,17 @@
 
 DEDIT(dedit_create)
 {
-	int j, i = maxDeity;
 	DEITY_DATA *pDeity;
-	struct deity_type *new_table;
 	char buf[MIL];
 
-	if (!IS_NULLSTR(argument) && deity_lookup(argument) == -1)
+	if (!IS_NULLSTR(argument) && deity_lookup(argument) == NULL)
 		sprintf(buf, argument);
 	else
 		sprintf(buf, "New Deity%d", maxDeity + 1);
 
-	maxDeity++;
-
-	alloc_mem(new_table, struct deity_type, maxDeity);
-
-	if (!new_table)
-	{
-		chprintln(ch, "Memory Allocation Failed!!! Unable to create deity.");
-		return FALSE;
-	}
-
-	for (j = 0; j < i; j++)
-		new_table[j] = deity_table[j];
-
-	free_mem(deity_table);
-	deity_table = new_table;
-
-	deity_table[i].name = str_dup(buf);
-	deity_table[i].desc = &str_empty[0];
-	deity_table[i].skillname = &str_empty[0];
-
-	pDeity = &deity_table[i];
+	pDeity = new_deity();
+	replace_string(pDeity->name, buf);
+	LINK(pDeity, deity_first, deity_last, next, prev);
 	edit_start(ch, pDeity, ED_DEITY);
 	chprintln(ch, "Deity created.");
 	return TRUE;
@@ -213,31 +176,10 @@
 		return FALSE;
 	}
 	else
-
 	{
-		int i, j = 0, c;
-		struct deity_type *new_table;
-
-		alloc_mem(new_table, struct deity_type, maxDeity);
-
-		if (!new_table)
-		{
-			chprintln(ch,
-					  "Memory Allocation error!!! Unable to delete liquid.");
-			return FALSE;
-		}
-
-		c = deity_lookup(pDeity->name);
-
-		for (i = 0; i < maxDeity; i++)
-			if (i != c)
-				new_table[j++] = deity_table[i];
-
-		free_mem(deity_table);
-		deity_table = new_table;
-		maxDeity--;
-
-		pDeity = &deity_table[0];
+		UNLINK(pDeity, deity_first, deity_last, next, prev);
+		free_deity(pDeity);
+		pDeity = deity_first;
 		ch->desc->pEdit = (void *) pDeity;
 
 		chprintln(ch, "Deity deleted.");
diff -ur src/olc_race.c new/olc_race.c
--- src/olc_race.c	Thu Mar 20 17:32:38 2003
+++ new/olc_race.c	Thu Mar 27 02:17:55 2003
@@ -36,64 +36,23 @@
 #include "lookup.h"
 #include "interp.h"
 #include "tables.h"
+#include "recycle.h"
 
 #define RAEDIT(fun)     bool fun (CHAR_DATA *ch, const char *argument)
 
 RAEDIT(raedit_create)
 {
-	int j, i = maxRace;
-	int x = 0;
 	RACE_DATA *pRace;
-	struct race_type *new_table;
 	char buf[MIL];
 
-	if (!IS_NULLSTR(argument) && race_lookup(argument) == -1)
+	if (!IS_NULLSTR(argument) && race_lookup(argument) == NULL)
 		sprintf(buf, argument);
 	else
 		sprintf(buf, "New Race%d", maxRace + 1);
 
-	maxRace++;
-
-	alloc_mem(new_table, struct race_type, maxRace + 1);
-
-	if (!new_table)
-	{
-		chprintln(ch, "Memory Allocation Failed!!! Unable to create race.");
-		return FALSE;
-	}
-
-	for (j = 0; j < i; j++)
-		new_table[j] = race_table[j];
-
-	free_mem(race_table);
-	race_table = new_table;
-
-	race_table[i].name = str_dup(buf);
-	race_table[i].who_name = str_dup("");
-	race_table[i].pc_race = FALSE;
-	race_table[i].act = 0;
-	race_table[i].aff = 0;
-	race_table[i].off = 0;
-	race_table[i].imm = 0;
-	race_table[i].res = 0;
-	race_table[i].vuln = 0;
-	race_table[i].form = 0;
-	race_table[i].parts = 0;
-
-	for (x = 0; x < 5; x++)
-		race_table[i].skills[x] = NULL;
-
-	for (x = 0; x < STAT_MAX; x++)
-	{
-		race_table[i].stats[x] = 0;
-		race_table[i].max_stats[x] = 0;
-	}
-	alloc_mem(race_table[i].class_mult, int, maxClass);
-
-	race_table[i].points = 0;
-	race_table[i].size = SIZE_MEDIUM;
-	race_table[maxRace].name = NULL;
-	pRace = &race_table[i];
+	pRace = new_race();
+	replace_string(pRace->name, buf);
+	LINK(pRace, race_first, race_last, next, prev);
 	edit_start(ch, pRace, ED_RACE);
 	chprintln(ch, "Race created.");
 	return TRUE;
@@ -101,18 +60,18 @@
 
 RAEDIT(raedit_list)
 {
-	int i;
+	RACE_DATA *i;
 	int count = 0;
 
 	chprintln(ch, "Num  Race Name\n\r"
 			  "-----------------------------------------------");
 
-	for (i = 0; i < maxRace; i++)
+	for (i = race_first; i; i = i->next)
 	{
-		if (!IS_NULLSTR(race_table[i].name))
+		if (!IS_NULLSTR(i->name))
 		{
 			count++;
-			chprintlnf(ch, "[%2d]  %-30s", i + 1, race_table[i].name);
+			chprintlnf(ch, "[%2d]  %-30s", count, i->name);
 		}
 	}
 
@@ -417,8 +376,7 @@
 	RACE_DATA *pRace;
 	CHAR_DATA *rch;
 	MOB_INDEX_DATA *mch;
-	vnum_t vnum;
-	int nMatch;
+	int ihash;
 
 	EDIT_RACE(ch, pRace);
 
@@ -431,62 +389,32 @@
 	else
 
 	{
-		int i, j = 0, c;
-		struct race_type *new_table;
-
-		alloc_mem(new_table, struct race_type, maxRace);
-
-		if (!new_table)
-		{
-			chprintln(ch, "Memory Allocation error!!! Unable to delete race.");
-			return FALSE;
-		}
-
-		c = race_lookup(pRace->name);
-
-		nMatch = 0;
-
-		for (vnum = 0; nMatch < top_mob_index; vnum++)
+		for (ihash = 0; ihash < MAX_KEY_HASH; ihash++)
 		{
-			if ((mch = get_mob_index(vnum)) == NULL)
-				continue;
-
-			nMatch++;
-
-			if (mch->race == c)
+			for (mch = mob_index_hash[ihash]; mch; mch = mch->next)
 			{
-				mch->race = race_lookup("unique");
-				SET_BIT(mch->area->area_flags, AREA_CHANGED);
-			}
-			else if (mch->race > c)
-			{
-				mch->race -= 1;
-				SET_BIT(mch->area->area_flags, AREA_CHANGED);
+				if (mch->race == pRace)
+				{
+					mch->race = race_lookup("unique");
+					SET_BIT(mch->area->area_flags, AREA_CHANGED);
+				}
 			}
 		}
 
 		for (rch = char_first; rch != NULL; rch = rch->next)
 		{
-			if (rch->race == c)
+			if (rch->race == pRace)
 			{
 				if (IS_NPC(rch))
 					rch->race = race_lookup("unique");
 				else
 					rch->race = race_lookup("human");
 			}
-			else if (rch->race > c)
-				rch->race -= 1;
 		}
 
-		for (i = 0; i < maxRace; i++)
-			if (i != c)
-				new_table[j++] = race_table[i];
-
-		free_mem(race_table);
-		race_table = new_table;
-		maxRace--;
-
-		pRace = &race_table[0];
+		UNLINK(pRace, race_first, race_last, next, prev);
+		free_race(pRace);
+		pRace = race_first;
 		edit_start(ch, pRace, ED_RACE);
 		chprintln(ch, "Race deleted.");
 	}
diff -ur src/olc_save.c new/olc_save.c
--- src/olc_save.c	Thu Mar 20 17:32:38 2003
+++ new/olc_save.c	Thu Mar 27 02:17:55 2003
@@ -215,7 +215,7 @@
  ****************************************************************************/
 void save_mobile(FILE * fp, MOB_INDEX_DATA * pMobIndex)
 {
-	int race = pMobIndex->race;
+	RACE_DATA *race = pMobIndex->race;
 	PROG_LIST *pMprog;
 	flag_t temp;
 
@@ -224,7 +224,7 @@
 	fprintf(fp, "%s~\n", pMobIndex->short_descr);
 	fprintf(fp, "%s~\n", fix_string(pMobIndex->long_descr));
 	fprintf(fp, "%s~\n", fix_string(pMobIndex->description));
-	fprintf(fp, "%s~\n", race_table[race].name);
+	fprintf(fp, "%s~\n", race->name);
 	fprintf(fp, "%s ", fwrite_flags(pMobIndex->act));
 	fprintf(fp, "%s ", fwrite_flags(pMobIndex->affected_by));
 	fprintf(fp, "%d %ld\n", pMobIndex->alignment, pMobIndex->group);
@@ -255,28 +255,28 @@
 	fprintf(fp, "%s\n",
 			IS_NULLSTR(pMobIndex->material) ? pMobIndex->material : "unknown");
 
-	if ((temp = DIF(race_table[race].act, pMobIndex->act)))
+	if ((temp = DIF(race->act, pMobIndex->act)))
 		fprintf(fp, "F act %s\n", fwrite_flags(temp));
 
-	if ((temp = DIF(race_table[race].aff, pMobIndex->affected_by)))
+	if ((temp = DIF(race->aff, pMobIndex->affected_by)))
 		fprintf(fp, "F aff %s\n", fwrite_flags(temp));
 
-	if ((temp = DIF(race_table[race].off, pMobIndex->off_flags)))
+	if ((temp = DIF(race->off, pMobIndex->off_flags)))
 		fprintf(fp, "F off %s\n", fwrite_flags(temp));
 
-	if ((temp = DIF(race_table[race].imm, pMobIndex->imm_flags)))
+	if ((temp = DIF(race->imm, pMobIndex->imm_flags)))
 		fprintf(fp, "F imm %s\n", fwrite_flags(temp));
 
-	if ((temp = DIF(race_table[race].res, pMobIndex->res_flags)))
+	if ((temp = DIF(race->res, pMobIndex->res_flags)))
 		fprintf(fp, "F res %s\n", fwrite_flags(temp));
 
-	if ((temp = DIF(race_table[race].vuln, pMobIndex->vuln_flags)))
+	if ((temp = DIF(race->vuln, pMobIndex->vuln_flags)))
 		fprintf(fp, "F vul %s\n", fwrite_flags(temp));
 
-	if ((temp = DIF(race_table[race].form, pMobIndex->form)))
+	if ((temp = DIF(race->form, pMobIndex->form)))
 		fprintf(fp, "F for %s\n", fwrite_flags(temp));
 
-	if ((temp = DIF(race_table[race].parts, pMobIndex->parts)))
+	if ((temp = DIF(race->parts, pMobIndex->parts)))
 		fprintf(fp, "F par %s\n", fwrite_flags(temp));
 
 	for (pMprog = pMobIndex->first_mprog; pMprog; pMprog = pMprog->next)
@@ -597,8 +597,8 @@
 					pRoomIndex->heal_rate != 100)
 					fprintf(fp, "M %d H %d\n",
 							pRoomIndex->mana_rate, pRoomIndex->heal_rate);
-				if (pRoomIndex->clan > -1)
-					fprintf(fp, "C %s~\n", clan_table[pRoomIndex->clan].name);
+				if (pRoomIndex->clan != NULL)
+					fprintf(fp, "C %s~\n", pRoomIndex->clan->name);
 
 				if (!IS_NULLSTR(pRoomIndex->owner))
 					fprintf(fp, "O %s~\n", pRoomIndex->owner);
diff -ur src/olc_social.c new/olc_social.c
--- src/olc_social.c	Thu Mar 20 17:32:38 2003
+++ new/olc_social.c	Thu Mar 27 02:17:55 2003
@@ -42,35 +42,26 @@
 #include "merc.h"
 #include "db.h"
 #include "olc.h"
+#include "recycle.h"
 
 #define SEDIT( fun )		bool fun( CHAR_DATA *ch, const char *argument )
 
 /* Find a social based on name */
-int social_lookup(const char *name)
+SOCIAL_DATA *social_lookup(const char *name)
 {
-	int i;
+	SOCIAL_DATA *i;
 
-	for (i = 0; i < maxSocial; i++)
-		if (!str_cmp(name, social_table[i].name))
+	for (i = social_first; i; i = i->next)
+		if (!str_cmp(name, i->name))
 			return i;
 
-	return -1;
+	return NULL;
 }
 
 /*
  * Social editting command
  */
 
-SOCIAL_DATA *get_social_data(const char *name)
-{
-	int i;
-
-	for (i = 0; i < maxSocial; i++)
-		if (!str_cmp(name, social_table[i].name))
-			return &social_table[i];
-	return NULL;
-}
-
 SEDIT(sedit_show)
 {
 	SOCIAL_DATA *pSocial;
@@ -78,7 +69,7 @@
 	if (IS_NULLSTR(argument))
 		EDIT_SOCIAL(ch, pSocial);
 	else
-		pSocial = get_social_data(argument);
+		pSocial = social_lookup(argument);
 
 	if (pSocial == NULL)
 	{
@@ -109,22 +100,12 @@
 
 SEDIT(sedit_delete)
 {
-	int i, j;
 	SOCIAL_DATA *pSocial;
-	struct social_type *new_table;
-
-	new_table = (struct social_type *) calloc(sizeof(*new_table), maxSocial);
-
-	if (!new_table)
-	{
-		chprintln(ch, "Memory allocation failed. Brace for impact...");
-		return FALSE;
-	}
 
 	if (IS_NULLSTR(argument))
 		EDIT_SOCIAL(ch, pSocial);
 	else
-		pSocial = get_social_data(argument);
+		pSocial = social_lookup(argument);
 
 	if (pSocial == NULL)
 	{
@@ -132,17 +113,8 @@
 		return FALSE;
 	}
 
-	for (i = 0, j = 0; i < maxSocial + 1; i++)
-	{
-		if (&social_table[i] != pSocial)
-		{
-			new_table[j] = social_table[i];
-			j++;
-		}
-	}
-	free(social_table);
-	social_table = new_table;
-	maxSocial--;
+	UNLINK(pSocial, social_first, social_last, next, prev);
+	free_social(pSocial);
 	edit_done(ch);
 	chprintln(ch, "Social deleted.");
 	return TRUE;
@@ -150,10 +122,8 @@
 
 SEDIT(sedit_create)
 {
-	int iSocial;
 	SOCIAL_DATA *pSocial;
 	char arg[MAX_INPUT_LENGTH];
-	struct social_type *new_table;
 
 	argument = one_argument(argument, arg);
 
@@ -162,34 +132,15 @@
 		chprintln(ch, "Syntax: sedit create [social]");
 		return FALSE;
 	}
-	if ((iSocial = social_lookup(arg)) != -1)
+	if (social_lookup(arg) != NULL)
 	{
 		chprintln(ch, "A social with that name already exists.");
 		return FALSE;
 	}
-	maxSocial++;
-	new_table =
-		(struct social_type *) realloc(social_table,
-									   sizeof(struct
-											  social_type) * (maxSocial + 1));
-
-	if (!new_table)
-	{
-		chprintln(ch, "Memory allocation failed. Brace for impact...");
-		return FALSE;
-	}
-	social_table = new_table;
-	replace_string(social_table[maxSocial - 1].name, arg);
-	replace_string(social_table[maxSocial - 1].char_no_arg, "");
-	replace_string(social_table[maxSocial - 1].others_no_arg, "");
-	replace_string(social_table[maxSocial - 1].char_found, "");
-	replace_string(social_table[maxSocial - 1].others_found, "");
-	replace_string(social_table[maxSocial - 1].vict_found, "");
-	replace_string(social_table[maxSocial - 1].char_auto, "");
-	replace_string(social_table[maxSocial - 1].others_auto, "");
-	replace_string(social_table[maxSocial].name, "");
-
-	pSocial = get_social_data(arg);
+	pSocial = new_social();
+	replace_string(pSocial->name, arg);
+	add_social(pSocial);
+	LINK(pSocial, social_first, social_last, next, prev);
 	edit_start(ch, pSocial, ED_SOCIAL);
 	chprintln(ch, "Social created.");
 	return TRUE;
@@ -273,7 +224,7 @@
 		}
 	}
 
-	if ((pSocial = get_social_data(arg1)) != NULL)
+	if ((pSocial = social_lookup(arg1)) != NULL)
 	{
 		edit_start(ch, pSocial, ED_SOCIAL);
 		return;
@@ -286,4 +237,33 @@
 
 	chprintln(ch, "SEdit: There is no default social to edit.");
 	return;
+}
+
+SEDIT(sedit_name)
+{
+	bool relocate;
+	SOCIAL_DATA *psocial;
+	char arg1[MIL];
+
+	EDIT_SOCIAL(ch, psocial);
+
+	one_argument(argument, arg1);
+	if (IS_NULLSTR(arg1))
+	{
+		chprintln(ch, "Cannot clear name field!");
+		return FALSE;
+	}
+	if (arg1[0] != psocial->name[0])
+	{
+		unlink_social(psocial);
+		relocate = TRUE;
+	}
+	else
+		relocate = FALSE;
+
+	replace_string(psocial->name, arg1);
+	if (relocate)
+		add_social(psocial);
+	chprintln(ch, "Name set.");
+	return TRUE;
 }
diff -ur src/proto.h new/proto.h
--- src/proto.h	Thu Mar 20 17:32:38 2003
+++ new/proto.h	Thu Mar 27 02:17:55 2003
@@ -155,7 +155,7 @@
 int fread_number args((FILE * fp));
 flag_t fread_flag args((FILE * fp));
 const char *fread_string args((FILE * fp));
-const char *fread_string_eol args((FILE * fp));
+const char *freadline args((FILE * fp));
 void fread_to_eol args((FILE * fp));
 char *fread_word args((FILE * fp));
 flag_t flag_convert args((char letter));
@@ -421,7 +421,7 @@
 bool vnum_OK args((vnum_t lnum, vnum_t hnum));
 
 /* lookup.c */
-int race_lookup args((const char *name));
+RACE_DATA *race_lookup args((const char *name));
 int item_lookup args((const char *name));
 int liq_lookup args((const char *name));
 
@@ -482,7 +482,7 @@
 void load_clans args((void));
 void load_commands args((void));
 void save_commands args((void));
-int command_lookup args((const char *name));
+CMD_DATA *command_lookup args((const char *name));
 void save_skills args((void));
 void load_skills args((void));
 void save_groups args((void));
@@ -557,7 +557,6 @@
 
 int check_buddy args((CHAR_DATA * ch, CHAR_DATA * fch));
 
-int srt_cmds_name args((const void *p1, const void *p2));
 int sort_socials args((void));
 int sort_helps args((void));
 int srt_skills args((const void *p1, const void *p2));
@@ -569,6 +568,15 @@
 void save_members args((void));
 void update_members args((CHAR_DATA * ch, bool pdelete));
 void load_members args((void));
+
+void build_command_hash args((void));
+void build_social_hash args((void));
+void unlink_command args((CMD_DATA * command));
+void add_command args((CMD_DATA * command));
+
+void unlink_social args((SOCIAL_DATA * social));
+void add_social args((SOCIAL_DATA * social));
+SOCIAL_DATA *find_social args((const char *command));
 
 #undef	CD
 #undef	MID
diff -ur src/quest.c new/quest.c
--- src/quest.c	Thu Mar 20 17:32:38 2003
+++ new/quest.c	Thu Mar 27 02:17:55 2003
@@ -965,7 +965,7 @@
 			|| (IS_EVIL(victim) && IS_EVIL(ch) && chance(50))
 			|| (IS_GOOD(victim) && IS_GOOD(ch) && chance(50))
 			|| victim->pIndexData->vnum < 100
-			|| victim->in_room->clan > -1
+			|| victim->in_room->clan != NULL
 			|| IS_SET(victim->imm_flags, IMM_WEAPON | IMM_MAGIC)
 			|| IS_SET(victim->act,
 					  ACT_TRAIN | ACT_PRACTICE | ACT_IS_HEALER | ACT_PET
diff -ur src/recycle.c new/recycle.c
--- src/recycle.c	Thu Mar 20 17:32:38 2003
+++ new/recycle.c	Thu Mar 27 02:17:55 2003
@@ -36,6 +36,8 @@
 #include "merc.h"
 #include "recycle.h"
 #include "olc.h"
+#include "tables.h"
+#include "interp.h"
 
 /* stuff for recycling ban structures */
 BAN_DATA *ban_free;
@@ -243,10 +245,10 @@
 	ch->prefix = &str_empty[0];
 	ch->logon = current_time;
 	ch->lines = PAGELEN;
-	ch->clan = -1;
-	ch->invited = -1;
+	ch->clan = NULL;
+	ch->invited = NULL;
 	ch->rank = 0;
-	ch->deity = -1;
+	ch->deity = NULL;
 	for (i = 0; i < 4; i++)
 		ch->armor[i] = 100;
 	ch->position = POS_STANDING;
@@ -731,6 +733,65 @@
 	PUT_FREE(pwd, next, WPWD_free);
 }
 
+RACE_DATA *race_free;
+
+RACE_DATA *new_race(void)
+{
+	static RACE_DATA race_zero;
+	RACE_DATA *race;
+	int x;
+
+	GET_FREE(race, RACE_DATA, next, race_free);
+
+	*race = race_zero;
+
+	race->name = &str_empty[0];
+	race->who_name = &str_empty[0];
+	race->pc_race = FALSE;
+	race->act = 0;
+	race->aff = 0;
+	race->off = 0;
+	race->imm = 0;
+	race->res = 0;
+	race->vuln = 0;
+	race->form = 0;
+	race->parts = 0;
+
+	for (x = 0; x < 5; x++)
+		race->skills[x] = NULL;
+
+	for (x = 0; x < STAT_MAX; x++)
+	{
+		race->stats[x] = 0;
+		race->max_stats[x] = 0;
+	}
+	alloc_mem(race->class_mult, int, maxClass);
+
+	race->points = 0;
+	race->size = SIZE_MEDIUM;
+	maxRace++;
+	VALIDATE(race);
+	return race;
+}
+
+void free_race(RACE_DATA * race)
+{
+	int x;
+
+	if (!IS_VALID(race))
+		return;
+
+	free_string(race->name);
+	free_string(race->who_name);
+	for (x = 0; x < 5; x++)
+		free_string(race->skills[x]);
+	free_mem(race->class_mult);
+
+	maxRace--;
+	INVALIDATE(race);
+	PUT_FREE(race, next, race_free);
+}
+
 MBR_DATA *new_mbr(void)
 {
 	static MBR_DATA mbr_zero;
@@ -740,7 +801,7 @@
 
 	*mbr = mbr_zero;
 	mbr->name = &str_empty[0];
-	mbr->clan = -1;
+	mbr->clan = NULL;
 	mbr->rank = 0;
 	VALIDATE(mbr);
 	return mbr;
@@ -755,4 +816,159 @@
 
 	INVALIDATE(mbr);
 	PUT_FREE(mbr, next, mbr_free);
+}
+
+SOCIAL_DATA *social_free;
+
+SOCIAL_DATA *new_social(void)
+{
+	static SOCIAL_DATA social_zero;
+	SOCIAL_DATA *soc;
+
+	GET_FREE(soc, SOCIAL_DATA, next, social_free);
+
+	*soc = social_zero;
+
+	soc->name = &str_empty[0];
+	soc->char_no_arg = &str_empty[0];
+	soc->others_no_arg = &str_empty[0];
+	soc->char_found = &str_empty[0];
+	soc->others_found = &str_empty[0];
+	soc->vict_found = &str_empty[0];
+	soc->char_not_found = &str_empty[0];
+	soc->char_auto = &str_empty[0];
+	soc->others_auto = &str_empty[0];
+
+	maxSocial++;
+	VALIDATE(soc);
+	return soc;
+}
+
+void free_social(SOCIAL_DATA * soc)
+{
+	if (!IS_VALID(soc))
+		return;
+
+	free_string(soc->name);
+	free_string(soc->char_no_arg);
+	free_string(soc->others_no_arg);
+	free_string(soc->char_found);
+	free_string(soc->others_found);
+	free_string(soc->vict_found);
+	free_string(soc->char_not_found);
+	free_string(soc->char_auto);
+	free_string(soc->others_auto);
+
+	maxSocial--;
+	INVALIDATE(soc);
+	PUT_FREE(soc, next, social_free);
+}
+
+DEITY_DATA *deity_free;
+
+DEITY_DATA *new_deity(void)
+{
+	static DEITY_DATA deity_zero;
+	DEITY_DATA *deity;
+
+	GET_FREE(deity, DEITY_DATA, next, deity_free);
+
+	*deity = deity_zero;
+
+	deity->name = &str_empty[0];
+	deity->desc = &str_empty[0];
+	deity->skillname = &str_empty[0];
+
+	maxDeity++;
+	VALIDATE(deity);
+	return deity;
+}
+
+void free_deity(DEITY_DATA * deity)
+{
+	if (!IS_VALID(deity))
+		return;
+
+	free_string(deity->name);
+	free_string(deity->desc);
+	free_string(deity->skillname);
+
+	maxDeity--;
+	INVALIDATE(deity);
+	PUT_FREE(deity, next, deity_free);
+}
+
+CLAN_DATA *clan_free;
+
+CLAN_DATA *new_clan(void)
+{
+	static CLAN_DATA clan_zero;
+	CLAN_DATA *clan;
+	int x;
+
+	GET_FREE(clan, CLAN_DATA, next, clan_free);
+
+	*clan = clan_zero;
+
+	clan->name = &str_empty[0];
+	clan->who_name = &str_empty[0];
+
+	for (x = 0; x < MAX_RANK; x++)
+		clan->rank[x].rankname = &str_empty[0];
+
+	maxClan++;
+	VALIDATE(clan);
+	return clan;
+}
+
+void free_clan(CLAN_DATA * clan)
+{
+	int x;
+
+	if (!IS_VALID(clan))
+		return;
+
+	free_string(clan->name);
+	free_string(clan->who_name);
+	for (x = 0; x < MAX_RANK; x++)
+		free_string(clan->rank[x].rankname);
+
+	maxClan--;
+	INVALIDATE(clan);
+	PUT_FREE(clan, next, clan_free);
+}
+
+CMD_DATA *cmd_free;
+
+CMD_DATA *new_command(void)
+{
+	static CMD_DATA cmd_zero;
+	CMD_DATA *cmd;
+
+	GET_FREE(cmd, CMD_DATA, next, cmd_free);
+
+	*cmd = cmd_zero;
+
+	cmd->name = &str_empty[0];
+	cmd->do_fun = do_null;
+	cmd->level = 0;
+	cmd->position = POS_DEAD;
+	cmd->show = TRUE;
+	cmd->log = LOG_NORMAL;
+
+	maxCommands++;
+	VALIDATE(cmd);
+	return cmd;
+}
+
+void free_command(CMD_DATA * cmd)
+{
+	if (!IS_VALID(cmd))
+		return;
+
+	free_string(cmd->name);
+
+	maxCommands--;
+	INVALIDATE(cmd);
+	PUT_FREE(cmd, next, cmd_free);
 }
diff -ur src/recycle.h new/recycle.h
--- src/recycle.h	Thu Mar 20 17:32:38 2003
+++ new/recycle.h	Thu Mar 27 02:17:55 2003
@@ -147,4 +147,19 @@
 MBR_DATA *new_mbr args((void));
 void free_mbr args((MBR_DATA * mbr));
 
+RACE_DATA *new_race args((void));
+void free_race args((RACE_DATA * race));
+
+SOCIAL_DATA *new_social args((void));
+void free_social args((SOCIAL_DATA * soc));
+
+DEITY_DATA *new_deity args((void));
+void free_deity args((DEITY_DATA * deity));
+
+CLAN_DATA *new_clan args((void));
+void free_clan args((CLAN_DATA * clan));
+
+CMD_DATA *new_command args((void));
+void free_command args((CMD_DATA * cmd));
+
 #endif
diff -ur src/save.c new/save.c
--- src/save.c	Thu Mar 20 17:32:38 2003
+++ new/save.c	Thu Mar 27 02:17:55 2003
@@ -134,10 +134,10 @@
 		fprintf(fp, "Desc %s~\n", ch->description);
 	if (ch->prompt != NULL || !str_cmp(ch->prompt, "<%hhp %mm %vmv> "))
 		fprintf(fp, "Prom %s~\n", ch->prompt);
-	fprintf(fp, "Race %s~\n", race_table[ch->race].name);
-	if (ch->clan > -1)
+	fprintf(fp, "Race %s~\n", ch->race->name);
+	if (ch->clan != NULL)
 	{
-		fprintf(fp, "Clan %s~\n", clan_table[ch->clan].name);
+		fprintf(fp, "Clan %s~\n", ch->clan->name);
 		fprintf(fp, "Rank %d\n", ch->rank);
 	}
 	fprintf(fp, "Sex  %d\n", ch->sex);
@@ -272,8 +272,8 @@
 		if (ch->pcdata->shares != 0)
 			fprintf(fp, "Shares %d\n", ch->pcdata->shares);
 
-		if (ch->deity != -1)
-			fprintf(fp, "Deity %s~\n", deity_table[ch->deity].name);
+		if (ch->deity != NULL)
+			fprintf(fp, "Deity %s~\n", ch->deity->name);
 
 		if (ON_GQUEST(ch) || (gquest_info.running != GQUEST_OFF
 							  && count_gqmobs(ch) == gquest_info.mob_count))
@@ -384,9 +384,9 @@
 	if (pet->description != pet->pIndexData->description)
 		fprintf(fp, "Desc %s~\n", pet->description);
 	if (pet->race != pet->pIndexData->race)
-		fprintf(fp, "Race %s~\n", race_table[pet->race].name);
-	if (pet->clan > -1)
-		fprintf(fp, "Clan %s~\n", clan_table[pet->clan].name);
+		fprintf(fp, "Race %s~\n", pet->race->name);
+	if (pet->clan != NULL)
+		fprintf(fp, "Clan %s~\n", pet->clan->name);
 	fprintf(fp, "Sex  %d\n", pet->sex);
 	if (pet->level != pet->pIndexData->level)
 		fprintf(fp, "Levl %d\n", pet->level);
@@ -691,21 +691,21 @@
 		if (ch->race == 0)
 			ch->race = race_lookup("human");
 
-		ch->size = race_table[ch->race].size;
+		ch->size = ch->race->size;
 		ch->dam_type = 17;		/*punch */
 
 		for (i = 0; i < 5; i++)
 		{
-			if (race_table[ch->race].skills[i] == NULL)
+			if (ch->race->skills[i] == NULL)
 				break;
-			group_add(ch, race_table[ch->race].skills[i], FALSE);
+			group_add(ch, ch->race->skills[i], FALSE);
 		}
-		ch->affected_by = ch->affected_by | race_table[ch->race].aff;
-		ch->imm_flags = ch->imm_flags | race_table[ch->race].imm;
-		ch->res_flags = ch->res_flags | race_table[ch->race].res;
-		ch->vuln_flags = ch->vuln_flags | race_table[ch->race].vuln;
-		ch->form = race_table[ch->race].form;
-		ch->parts = race_table[ch->race].parts;
+		ch->affected_by = ch->affected_by | ch->race->aff;
+		ch->imm_flags = ch->imm_flags | ch->race->imm;
+		ch->res_flags = ch->res_flags | ch->race->res;
+		ch->vuln_flags = ch->vuln_flags | ch->race->vuln;
+		ch->form = ch->race->form;
+		ch->parts = ch->race->parts;
 
 		if (d != NULL)
 		{
diff -ur src/tables.h new/tables.h
--- src/tables.h	Thu Mar 20 17:32:38 2003
+++ new/tables.h	Thu Mar 27 02:17:55 2003
@@ -30,7 +30,6 @@
 #define TABLES_H
 
 /* game tables */
-extern struct clan_type *clan_table;
 extern const struct position_type position_table[];
 extern const struct sex_type sex_table[];
 extern const struct size_type size_table[];
@@ -90,7 +89,6 @@
 
 struct clan_rank
 {
-	const char *shortname;
 	const char *rankname;
 };
 
@@ -101,6 +99,8 @@
 	vnum_t hall;
 	bool independent;			/* true for loners */
 	RANK_DATA rank[MAX_RANK];
+	CLAN_DATA *next, *prev;
+	bool valid;
 };
 
 struct position_type
diff -ur src/tablesave.c new/tablesave.c
--- src/tablesave.c	Thu Mar 20 17:32:38 2003
+++ new/tablesave.c	Thu Mar 27 02:17:55 2003
@@ -114,9 +114,14 @@
 
 const char *race_str(void *temp)
 {
-	int *raza = (int *) temp;
+	RACE_DATA **raza = (RACE_DATA **) temp;
+	RACE_DATA *tmp;
 
-	return race_table[*raza].name;
+	for (tmp = race_first; tmp; tmp = tmp->next)
+		if (tmp == *raza)
+			return tmp->name;
+
+	return "unique";
 }
 
 const char *pgsn_str(void *temp)
@@ -190,19 +195,23 @@
 
 const char *clan_str(void *temp)
 {
-	int *clan = (int *) temp;
+	CLAN_DATA **clan = (CLAN_DATA **) temp;
+	CLAN_DATA *tmp;
+
+	for (tmp = clan_first; tmp; tmp = tmp->next)
+		if (tmp == *clan)
+			return tmp->name;
 
-	return clan_table[*clan].name;
+	return "unknown";
 }
 
 bool clan_read(void *temp, char *arg)
 {
-	int *posic = (int *) temp;
-	int ffg = clan_lookup(arg);
+	CLAN_DATA **posic = (CLAN_DATA **) temp;
 
-	*posic = UMAX(0, ffg);
+	*posic = clan_lookup(arg);
 
-	if (ffg == -1)
+	if (*posic == NULL)
 		return FALSE;
 	else
 		return TRUE;
@@ -568,7 +577,7 @@
 						(RANK_DATA *) ((int) temp->puntero_field -
 									   (int) typebase + (int) puntero);
 					i = fread_number(fp);
-					rdata[i - 1].shortname = fread_string(fp);
+					//fread_string(fp);
 					rdata[i - 1].rankname = fread_string(fp);
 					found = TRUE, cnt++;
 					break;
@@ -762,8 +771,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;
@@ -776,8 +785,7 @@
 			{
 				fprintf(fp, "%s\t%s%d ", temp->field,
 						strlen(temp->field) < 8 ? "\t" : "", i + 1);
-				fprintf(fp, "%s~ %s~\n", fix_string(rdata[i].shortname),
-						fix_string(rdata[i].rankname));
+				fprintf(fp, "%s~\n", fix_string(rdata[i].rankname));
 			}
 			break;
 
@@ -792,7 +800,7 @@
 void save_commands(void)
 {
 	FILE *fp;
-	int i;
+	CMD_DATA *i;
 #if !defined(WIN32)
 	const char *TEMPFILE = COMMAND_FILE ".tmp";
 
@@ -808,15 +816,15 @@
 		return;
 	}
 
-	fprintf(fp, "%d\n\n", maxCommands);
-
-	for (i = 0; i < maxCommands; ++i)
+	for (i = cmd_first; i; i = i->next)
 	{
 		fprintf(fp, "#COMMAND\n");
-		save_struct(fp, &cmd, cmdsavetable, &cmd_table[i]);
+		save_struct(fp, &cmd, cmdsavetable, i);
 		fprintf(fp, "#END\n\n");
 	}
 
+	fprintf(fp, "#!\n\n");
+
 	file_close(fp);
 #if !defined(WIN32)
 	rename(TEMPFILE, COMMAND_FILE);
@@ -827,7 +835,7 @@
 {
 	FILE *fp;
 	static CMD_DATA emptycmd;
-	int i = 0, largo;
+	CMD_DATA *i;
 	const char *word;
 
 	fp = file_open(COMMAND_FILE, "r");
@@ -839,20 +847,12 @@
 		return;
 	}
 
-	largo = fread_number(fp);
-
-	maxCommands = largo;
-
-	alloc_mem(cmd_table, CMD_DATA, largo + 1);
-
-	for (i = 0; i <= largo; i++)
-		cmd_table[i] = emptycmd;
-
-	i = 0;
-
 	while (TRUE)
 	{
-		word = fread_word(fp);
+		word = feof(fp) ? "#!" : fread_word(fp);
+
+		if (!str_cmp(word, "#!"))
+			break;
 
 		if (str_cmp(word, "#COMMAND"))
 		{
@@ -861,14 +861,10 @@
 			return;
 		}
 
-		load_struct(fp, &cmd, cmdsavetable, &cmd_table[i++]);
-
-		if (i == largo)
-		{
-			file_close(fp);
-			cmd_table[i].name = str_dup(str_empty);
-			return;
-		}
+		i = new_command();
+		*i = emptycmd;
+		load_struct(fp, &cmd, cmdsavetable, i);
+		LINK(i, cmd_first, cmd_last, next, prev);
 	}
 }
 
@@ -965,7 +961,6 @@
 {
 	FILE *fp;
 	RACE_DATA *temp;
-	int cnt = 0;
 #if !defined(WIN32)
 	const char *TEMPFILE = RACE_FILE ".tmp";
 
@@ -980,20 +975,15 @@
 		return;
 	}
 
-	for (temp = race_table; !IS_NULLSTR(temp->name); temp = temp++)
-	{
-		cnt++;
-	}
-
-	fprintf(fp, "%d\n", cnt);
-
-	for (temp = race_table; !IS_NULLSTR(temp->name); temp = temp++)
+	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, "#!\n\n");
+
 	file_close(fp);
 
 #if !defined(WIN32)
@@ -1006,7 +996,7 @@
 {
 	FILE *fp;
 	const char *word;
-	int i;
+	RACE_DATA *pRace;
 
 	fp = file_open(RACE_FILE, "r");
 
@@ -1016,16 +1006,13 @@
 		return;
 	}
 
-	maxRace = fread_number(fp);
-
-	alloc_mem(race_table, RACE_DATA, maxRace + 1);
-
-	i = 0;
-
 	while (TRUE)
 	{
 		word = fread_word(fp);
 
+		if (!str_cmp(word, "#!"))
+			break;
+
 		if (str_cmp(word, "#RACE"))
 		{
 			bugf("word %s", word);
@@ -1033,15 +1020,9 @@
 			return;
 		}
 
-		load_struct(fp, &race, racesavetable, &race_table[i++]);
-
-		if (i == maxRace)
-		{
-			file_close(fp);
-			race_table[i].name = NULL;
-
-			return;
-		}
+		pRace = new_race();
+		load_struct(fp, &race, racesavetable, pRace);
+		LINK(pRace, race_first, race_last, next, prev);
 	}
 }
 
@@ -1226,7 +1207,7 @@
 void save_social_table(void)
 {
 	FILE *fp;
-	int i;
+	SOCIAL_DATA *i;
 #if !defined(WIN32)
 	const char *TEMPFILE = SOCIAL_FILE ".tmp";
 
@@ -1242,12 +1223,10 @@
 		return;
 	}
 
-	fprintf(fp, "%d\n", maxSocial);
-
-	for (i = 0; i < maxSocial; ++i)
+	for (i = social_first; i; i = i->next)
 	{
 		fprintf(fp, "#SOCIAL\n");
-		save_struct(fp, &soc, socialsavetable, &social_table[i]);
+		save_struct(fp, &soc, socialsavetable, i);
 		fprintf(fp, "#END\n\n");
 	}
 
@@ -1263,7 +1242,7 @@
 {
 	FILE *fp;
 	static SOCIAL_DATA socialzero;
-	int i = 0;
+	SOCIAL_DATA *pSocial;
 	const char *word;
 
 	fp = file_open(SOCIAL_FILE, "r");
@@ -1274,16 +1253,6 @@
 		exit(1);
 	}
 
-	fscanf(fp, "%d\n", &maxSocial);
-
-	alloc_mem(social_table, SOCIAL_DATA, maxSocial + 1);
-
-	if (!social_table)
-	{
-		bugf("Error! Social_table == NULL, MAX_SOCIAL : %d", maxSocial);
-		exit(1);
-	}
-
 	for (;;)
 	{
 		word = fread_word(fp);
@@ -1297,25 +1266,19 @@
 			exit(1);
 		}
 
-		if (i >= maxSocial)
-		{
-			bug("load_socials: number greater than maxSocial", 0);
-			exit(1);
-		}
-
-		social_table[i] = socialzero;
-		load_struct(fp, &soc, socialsavetable, &social_table[i++]);
+		pSocial = new_social();
+		*pSocial = socialzero;
+		load_struct(fp, &soc, socialsavetable, pSocial);
+		LINK(pSocial, social_first, social_last, next, prev);
 	}
 
-	social_table[maxSocial].name = NULL;
-
 	file_close(fp);
 }
 
 void save_clans(void)
 {
 	FILE *fp;
-	int i;
+	CLAN_DATA *i;
 #if !defined(WIN32)
 	const char *TEMPFILE = CLAN_FILE ".tmp";
 
@@ -1331,12 +1294,10 @@
 		return;
 	}
 
-	fprintf(fp, "%d\n", maxClan);
-
-	for (i = 0; i < maxClan; ++i)
+	for (i = clan_first; i; i = i->next)
 	{
 		fprintf(fp, "#CLAN\n");
-		save_struct(fp, &clan, clansavetable, &clan_table[i]);
+		save_struct(fp, &clan, clansavetable, i);
 		fprintf(fp, "#END\n\n");
 	}
 
@@ -1352,7 +1313,7 @@
 {
 	FILE *fp;
 	static CLAN_DATA clanzero;
-	int i = 0;
+	CLAN_DATA *i;
 	const char *word;
 
 	fp = file_open(CLAN_FILE, "r");
@@ -1363,16 +1324,6 @@
 		exit(1);
 	}
 
-	fscanf(fp, "%d\n", &maxClan);
-
-	alloc_mem(clan_table, CLAN_DATA, maxClan + 1);
-
-	if (!clan_table)
-	{
-		bugf("Error! Clan_table == NULL, MAX_CLAN : %d", maxClan);
-		exit(1);
-	}
-
 	for (;;)
 	{
 		word = fread_word(fp);
@@ -1386,18 +1337,12 @@
 			exit(1);
 		}
 
-		if (i >= maxClan)
-		{
-			bug("load_clans: number greater than maxClan", 0);
-			exit(1);
-		}
-
-		clan_table[i] = clanzero;
-		load_struct(fp, &clan, clansavetable, &clan_table[i++]);
+		i = new_clan();
+		*i = clanzero;
+		load_struct(fp, &clan, clansavetable, i);
+		LINK(i, clan_first, clan_last, next, prev);
 	}
 
-	clan_table[maxClan].name = NULL;
-
 	file_close(fp);
 }
 
@@ -1595,7 +1540,7 @@
 void save_deities(void)
 {
 	FILE *fp;
-	int i;
+	DEITY_DATA *i;
 #if !defined(WIN32)
 	char *TEMPFILE = DEITY_FILE ".tmp";
 
@@ -1611,12 +1556,10 @@
 		return;
 	}
 
-	fprintf(fp, "%d\n", maxDeity);
-
-	for (i = 0; i < maxDeity; ++i)
+	for (i = deity_first; i; i = i->next)
 	{
 		fprintf(fp, "#DEITY\n");
-		save_struct(fp, &deity, deitysavetable, &deity_table[i]);
+		save_struct(fp, &deity, deitysavetable, i);
 		fprintf(fp, "#END\n\n");
 	}
 
@@ -1632,7 +1575,7 @@
 {
 	FILE *fp;
 	static DEITY_DATA deityzero;
-	int i = 0;
+	DEITY_DATA *i;
 	const char *word;
 
 	fp = file_open(DEITY_FILE, "r");
@@ -1644,16 +1587,6 @@
 		return;
 	}
 
-	fscanf(fp, "%d\n", &maxDeity);
-
-	alloc_mem(deity_table, DEITY_DATA, maxDeity + 1);
-
-	if (!deity_table)
-	{
-		bugf("Error! Deity_table == NULL, MAX_DEITY : %d", maxDeity);
-		exit(1);
-	}
-
 	for (;;)
 	{
 		word = fread_word(fp);
@@ -1667,18 +1600,12 @@
 			exit(1);
 		}
 
-		if (i >= maxDeity)
-		{
-			bug("load_deities: number greater than maxDeity", 0);
-			exit(1);
-		}
-
-		deity_table[i] = deityzero;
-		load_struct(fp, &deity, deitysavetable, &deity_table[i++]);
+		i = new_deity();
+		*i = deityzero;
+		load_struct(fp, &deity, deitysavetable, i);
+		LINK(i, deity_first, deity_last, next, prev);
 	}
 
-	deity_table[maxDeity].name = NULL;
-
 	file_close(fp);
 }
 
@@ -1770,7 +1697,7 @@
 
 	for (pmbr = mbr_first; pmbr != NULL; pmbr = pmbr->next)
 	{
-		if (pmbr->clan < 0 || pmbr->clan >= maxClan)
+		if (pmbr->clan == NULL)
 		{
 			bugf("%s member data invalid.", pmbr->name);
 			continue;
diff -ur src/war.c new/war.c
--- src/war.c	Thu Mar 20 17:32:38 2003
+++ new/war.c	Thu Mar 27 02:17:55 2003
@@ -347,13 +347,13 @@
 	default:
 		return "";
 	case WAR_RACE:
-		return race_table[ch->race].name;
+		return ch->race->name;
 	case WAR_CLASS:
 		return class_table[ch->Class[0]].name;
 	case WAR_GENOCIDE:
 		return "";
 	case WAR_CLAN:
-		return clan_table[ch->clan].who_name;
+		return ch->clan->who_name;
 	}
 }
 
@@ -658,8 +658,7 @@
 	switch (war_info.wartype)
 	{
 	case WAR_RACE:
-		sprintf(buf, "{WThe {R%s's{W won this war.{x",
-				race_table[ch->race].name);
+		sprintf(buf, "{WThe {R%s's{W won this war.{x", ch->race->name);
 		add_buf(output, buf);
 		break;
 	case WAR_CLASS:
@@ -672,7 +671,7 @@
 		add_buf(output, buf);
 		break;
 	case WAR_CLAN:
-		sprintf(buf, "{R%s{W won this war.{x", clan_table[ch->clan].who_name);
+		sprintf(buf, "{R%s{W won this war.{x", ch->clan->who_name);
 		add_buf(output, buf);
 		break;
 	}
@@ -826,7 +825,7 @@
 		if (abort_race_war())
 		{
 			announce(NULL, INFO_WAR, "The %s's have won the War!",
-					 race_table[ch->race].name);
+					 ch->race->name);
 			note_war(ch);
 			for (wch = player_first; wch != NULL; wch = wch->next_player)
 			{
@@ -873,7 +872,7 @@
 		if (abort_clan_war())
 		{
 			announce(NULL, INFO_WAR, "%s has won the War!{x",
-					 clan_table[ch->clan].who_name);
+					 ch->clan->who_name);
 			note_war(ch);
 			for (wch = player_first; wch != NULL; wch = wch->next_player)
 			{
diff -ur src/webserver.c new/webserver.c
--- src/webserver.c	Thu Mar 20 17:32:38 2003
+++ new/webserver.c	Thu Mar 27 02:17:55 2003
@@ -1170,8 +1170,8 @@
 		else if (victim->in_room == victim->fighting->in_room)
 		{
 			strcat(buf,
-				   IS_NPC(victim) ? victim->fighting->
-				   short_descr : victim->fighting->name);
+				   IS_NPC(victim) ? victim->fighting->short_descr : victim->
+				   fighting->name);
 			strcat(buf, ".");
 		}
 		else
@@ -1294,7 +1294,8 @@
 {
 	int gn;
 	int sn, i;
-	int tn, race;
+	int tn;
+	RACE_DATA *race;
 	bool *displayed;
 	int past_default = TRUE;
 	char buf[MSL];
@@ -1444,11 +1445,11 @@
 	send_buf(wdesc->fd, "<TD>Race</TD>\n");
 	send_buf(wdesc->fd, "<TD>Skills</TD></TR>\n");
 
-	for (race = 0; race < maxRace; race++)
+	for (race = race_first; race; race = race->next)
 	{
-		if (!race_table[race].pc_race)
+		if (!race->pc_race)
 			continue;
-		send_buf(wdesc->fd, "<TR><TD>%s</TD><TD>\n", race_table[race].name);
+		send_buf(wdesc->fd, "<TR><TD>%s</TD><TD>\n", race->name);
 		buf[0] = '\0';
 		for (sn = 1; sn < maxSkill; sn++)
 		{
@@ -1456,9 +1457,9 @@
 				break;
 			for (i = 0; i < 5; i++)
 			{
-				if (race_table[race].skills[i] == NULL)
+				if (race->skills[i] == NULL)
 					break;
-				if (skill_lookup(race_table[race].skills[i]) == sn)
+				if (skill_lookup(race->skills[i]) == sn)
 				{
 					snprintf(buf2, MSL, "%s, ", skill_table[sn].name);
 					strncat(buf, buf2, MSL);
@@ -1533,8 +1534,7 @@
 			send_buf(wdesc->fd, "<TD>%d</TD>\n", wch->level);
 			send_buf(wdesc->fd,
 					 "<TD><A href=\"%sraces/%s\">%s</A></TD>\n",
-					 DEFAULT_URL_PORT(), race_table[wch->race].name,
-					 race_table[wch->race].name);
+					 DEFAULT_URL_PORT(), wch->race->name, wch->race->name);
 			send_buf(wdesc->fd, "<TD>%s</TD>\n", class_who(wch));
 		}
 		else
@@ -1545,10 +1545,10 @@
 
 		if (is_clan(wch))
 		{
-			html_colourconv(buf, clan_table[wch->clan].who_name);
+			html_colourconv(buf, wch->clan->who_name);
 			send_buf(wdesc->fd,
 					 "<TD><A href=\"%sclans/%s\">%s</A></TD>\n",
-					 DEFAULT_URL_PORT(), clan_table[wch->clan].name, buf);
+					 DEFAULT_URL_PORT(), wch->clan->name, buf);
 		}
 		else
 			send_buf(wdesc->fd, "<TD></TD>\n");
@@ -1653,40 +1653,32 @@
 
 void HandleCommandsRequest(WEB_DESCRIPTOR * wdesc)
 {
-	int i;
+	CMD_DATA *i;
 	int pos = 0;
 	HELP_DATA *pHelp;
 	int count = 0;
-	struct cmd_type *commands = NULL;
 
 	print_header(wdesc, "Commands");
 	send_buf(wdesc->fd, "<TABLE>\n");
-	alloc_mem(commands, struct cmd_type, maxCommands + 1);
-
-	commands =
-		(struct cmd_type *) memcpy(commands, cmd_table,
-								   sizeof(struct cmd_type) * maxCommands + 1);
 
-	qsort(commands, maxCommands, sizeof(cmd_table[0]), srt_cmds_name);
-	for (i = 0; i < maxCommands; i++)
+	for (i = cmd_first; i; i = i->next)
 	{
-		if (commands[i].level >= LEVEL_IMMORTAL || !commands[i].show)
+		if (i->level >= LEVEL_IMMORTAL || !i->show)
 			continue;
 		count = 0;
 		for (pHelp = help_first; pHelp; pHelp = pHelp->next)
 		{
 			count++;
-			if (is_name(commands[i].name, pHelp->keyword))
+			if (is_name(i->name, pHelp->keyword))
 				break;
 		}
 		if (pHelp)
 			send_buf(wdesc->fd, "%s<TD><A href=\"%shelps/%d\">%s</TD>\n",
 					 (pos == 0) ? "<TR>" : "", DEFAULT_URL_PORT(), count,
-					 commands[i].name);
+					 i->name);
 		else
 			send_buf(wdesc->fd,
-					 "%s<TD>%s</TD>\n",
-					 (pos == 0) ? "<TR>" : "", commands[i].name);
+					 "%s<TD>%s</TD>\n", (pos == 0) ? "<TR>" : "", i->name);
 		if (++pos % 5 == 0)
 		{
 			send_buf(wdesc->fd, "</TR>");
@@ -1695,7 +1687,6 @@
 	}
 	send_buf(wdesc->fd, "</TABLE>\n");
 	print_footer(wdesc);
-	free_mem(commands);
 }
 
 void HandleHelpsRequest(WEB_DESCRIPTOR * wdesc)
@@ -1753,7 +1744,7 @@
 
 void HandleRaceRequest(WEB_DESCRIPTOR * wdesc)
 {
-	int race;
+	RACE_DATA *race;
 
 	print_header(wdesc, "Races");
 	send_buf(wdesc->fd, "<TABLE><TR>\n");
@@ -1761,9 +1752,9 @@
 	send_buf(wdesc->fd,
 			 "<TD><I>Str</I></TD><TD><I>Int</I></TD><TD><I>Wis</I></TD><TD><I>Dex</I></TD><TD><I>Con</I></TD><TD><I>Luck</I></TD>\n");
 	send_buf(wdesc->fd, "<TD><I>Creation<BR>Points</I></TD></TR>\n");
-	for (race = 0; race_table[race].name != NULL; race++)
+	for (race = race_first; race != NULL; race = race->next)
 	{
-		if (!race_table[race].pc_race)
+		if (!race->pc_race)
 			continue;
 
 		send_buf(wdesc->fd, "<TR>\n");
@@ -1772,12 +1763,12 @@
 				 "races/%s\">%s</A></TD>\n<TD>%d</TD>\n<TD>%d</TD>\n<TD>%d</TD>\n"
 				 "<TD>%d</TD>\n<TD>%d</TD><TD ALIGN=\"center\">%d</TD></TR>\n",
 				 DEFAULT_URL_PORT(),
-				 race_table[race].name, race_table[race].name,
-				 race_table[race].max_stats[STAT_STR],
-				 race_table[race].max_stats[STAT_INT],
-				 race_table[race].max_stats[STAT_WIS],
-				 race_table[race].max_stats[STAT_DEX],
-				 race_table[race].max_stats[STAT_CON], race_table[race].points);
+				 race->name, race->name,
+				 race->max_stats[STAT_STR],
+				 race->max_stats[STAT_INT],
+				 race->max_stats[STAT_WIS],
+				 race->max_stats[STAT_DEX],
+				 race->max_stats[STAT_CON], race->points);
 	}
 	send_buf(wdesc->fd, "</TABLE>\n");
 	send_buf(wdesc->fd,
@@ -1788,13 +1779,13 @@
 	print_footer(wdesc);
 }
 
-void HandleRaceDumpRequest(WEB_DESCRIPTOR * wdesc, int race)
+void HandleRaceDumpRequest(WEB_DESCRIPTOR * wdesc, RACE_DATA * race)
 {
 	HELP_DATA *pHelp;
 	char buf[MSL * 2];
 
-	print_header(wdesc, race_table[race].name);
-	sprintf(buf, "%s race", race_table[race].name);
+	print_header(wdesc, race->name);
+	sprintf(buf, "%s", race->name);
 	if ((pHelp = help_lookup(buf)) != NULL)
 	{
 		html_colourconv(buf, pHelp->text);
@@ -1808,17 +1799,17 @@
 
 void HandleClanRequest(WEB_DESCRIPTOR * wdesc)
 {
-	int clan;
+	CLAN_DATA *clan;
 	char buf[MSL * 3];
 
 	print_header(wdesc, "Clans");
 	send_buf(wdesc->fd, "<TABLE>\n");
 	send_buf(wdesc->fd,
 			 "<TR><B><TD><I>Name</I></TD><TD><I>Description</I></TD><TD><I>Homepage</I></TD></TR>\n");
-	for (clan = 0; clan < maxClan; clan++)
+	for (clan = clan_first; clan; clan = clan->next)
 	{
 
-		html_colourconv(buf, clan_table[clan].who_name);
+		html_colourconv(buf, clan->who_name);
 
 		send_buf(wdesc->fd, "<TR><TD>%s</TD></TR>\n", buf);
 	}
@@ -2024,7 +2015,7 @@
 	send_buf(wdesc->fd, "<P>%s<br>", buf);
 	html_colourconv(buf, pMob->description);
 	send_buf(wdesc->fd, "%s<br>", buf);
-	send_buf(wdesc->fd, "Race: %s<br>", race_table[pMob->race].name);
+	send_buf(wdesc->fd, "Race: %s<br>", pMob->race->name);
 	send_buf(wdesc->fd, "Sex: %s<br>", sex_table[pMob->sex].name);
 	send_buf(wdesc->fd, "Alignment: %d<br>", pMob->alignment);
 	send_buf(wdesc->fd, "</P>");
@@ -2073,15 +2064,15 @@
 
 void HandleSocialsRequest(WEB_DESCRIPTOR * wdesc)
 {
-	int iSocial;
+	SOCIAL_DATA *iSocial;
+	int i;
 
 	print_header(wdesc, "Socials");
 	send_buf(wdesc->fd, "<TABLE><TR>\n");
-	for (iSocial = 0; !IS_NULLSTR(social_table[iSocial].name); iSocial++)
+	for (iSocial = social_first; iSocial; iSocial = iSocial->next)
 		send_buf(wdesc->fd, "%s<TD>%s</TD>\n",
-				 iSocial % 5 == 0 ? "</TR><TR>" : "",
-				 social_table[iSocial].name);
-	send_buf(wdesc->fd, "%s</TABLE>\n", iSocial % 5 != 0 ? "</TR>" : "");
+				 i++ % 5 == 0 ? "</TR><TR>" : "", iSocial->name);
+	send_buf(wdesc->fd, "%s</TABLE>\n", i % 5 != 0 ? "</TR>" : "");
 	print_footer(wdesc);
 }
 
@@ -2337,7 +2328,7 @@
 	}
 	else if (!str_prefix("races", path))
 	{
-		int race;
+		RACE_DATA *race;
 		char *buf;
 
 		if (!str_cmp(path, "races") || !str_cmp(path, "races/"))
@@ -2350,12 +2341,11 @@
 		if (!IS_NULLSTR(buf))
 		{
 			buf++;
-			for (race = 0; race < maxRace; race++)
+			for (race = race_first; race; race = race->next)
 			{
-				if (!str_cmp(race_table[race].name, buf))
+				if (!str_cmp(race->name, buf))
 				{
-					logf("Web Request: %s - Race %s", web_buf,
-						 race_table[race].name);
+					logf("Web Request: %s - Race %s", web_buf, race->name);
 					HandleRaceDumpRequest(wdesc, race);
 					return;
 				}