1stMUD/corefiles/
1stMUD/gods/
1stMUD/player/
1stMUD/win32/
1stMUD/win32/ROM/
/**************************************************************************
*  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
*  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
*                                                                         *
*  Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael         *
*  Chastain, Michael Quan, and Mitchell Tse.                              *
*                                                                         *
*  In order to use any part of this Merc Diku Mud, you must comply with   *
*  both the original Diku license in 'license.doc' as well the Merc       *
*  license in 'license.txt'.  In particular, you may not remove either of *
*  these copyright notices.                                               *
*                                                                         *
*  Much time and thought has gone into this software and you are          *
*  benefiting.  We hope that you share your changes too.  What goes       *
*  around, comes around.                                                  *
***************************************************************************
*       ROM 2.4 is copyright 1993-1998 Russ Taylor                        *
*       ROM has been brought to you by the ROM consortium                 *
*           Russ Taylor (rtaylor@hypercube.org)                           *
*           Gabrielle Taylor (gtaylor@hypercube.org)                      *
*           Brian Moore (zump@rom.org)                                    *
*       By using this code, you have agreed to follow the terms of the    *
*       ROM license, in the file Rom24/doc/rom.license                    *
***************************************************************************
*       1stMUD ROM Derivative (c) 2001-2002 by Ryan Jennings              *
*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
***************************************************************************/
/***************************************************************************
 *  File: olc.c                                                            *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 *                                                                         *
 *  This code was freely distributed with the The Isles 1.1 source code,   *
 *  and has been used here for OLC - OLC would not be what it is without   *
 *  all the previous coders who released their source code.                *
 *                                                                         *
 ***************************************************************************/

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if !defined(WIN32)
#include <unistd.h>
#endif
#include "merc.h"
#include "tables.h"
#include "olc.h"
#include "interp.h"
#include "lookup.h"

MOB_INDEX_DATA xMob;
OBJ_INDEX_DATA xObj;
ROOM_INDEX_DATA xRoom;
AREA_DATA xArea;
PROG_CODE xMProg;
PROG_CODE xOProg;
PROG_CODE xRProg;
HELP_DATA xHelp;
SOCIAL_DATA xSoc;
CLAN_DATA xClan;
CMD_DATA xCmd;
SKILL_DATA xSkill;
GROUP_DATA xGroup;
RACE_DATA xRace;
CLASS_DATA xClass;
DEITY_DATA xDeity;

/* Executed from comm.c.  Minimizes compiling when changes are made. */
bool run_olc_editor(DESCRIPTOR_DATA * d)
{
	switch (d->editor)
	{
	case ED_AREA:
		aedit(d->character, d->incomm);
		break;
	case ED_ROOM:
		redit(d->character, d->incomm);
		break;
	case ED_OBJECT:
		oedit(d->character, d->incomm);
		break;
	case ED_MOBILE:
		medit(d->character, d->incomm);
		break;
	case ED_MPCODE:
		mpedit(d->character, d->incomm);
		break;
	case ED_OPCODE:
		opedit(d->character, d->incomm);
		break;
	case ED_RPCODE:
		rpedit(d->character, d->incomm);
		break;
	case ED_HELP:
		hedit(d->character, d->incomm);
		break;
	case ED_SOCIAL:
		sedit(d->character, d->incomm);
		break;
	case ED_CLAN:
		cedit(d->character, d->incomm);
		break;
	case ED_CMD:
		cmdedit(d->character, d->incomm);
		break;
	case ED_SKILL:
		skedit(d->character, d->incomm);
		break;
	case ED_GROUP:
		gredit(d->character, d->incomm);
		break;
	case ED_RACE:
		raedit(d->character, d->incomm);
		break;
	case ED_CLASS:
		cledit(d->character, d->incomm);
		break;
	case ED_DEITY:
		dedit(d->character, d->incomm);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

char *olc_ed_name(CHAR_DATA * ch)
{
	static char buf[10];

	buf[0] = '\0';
	switch (ch->desc->editor)
	{
	case ED_AREA:
		sprintf(buf, "AEdit");
		break;
	case ED_ROOM:
		sprintf(buf, "REdit");
		break;
	case ED_OBJECT:
		sprintf(buf, "OEdit");
		break;
	case ED_MOBILE:
		sprintf(buf, "MEdit");
		break;
	case ED_MPCODE:
		sprintf(buf, "MPEdit");
		break;
	case ED_OPCODE:
		sprintf(buf, "OPEdit");
		break;
	case ED_RPCODE:
		sprintf(buf, "RPEdit");
		break;
	case ED_HELP:
		sprintf(buf, "HEdit");
		break;
	case ED_SOCIAL:
		sprintf(buf, "sEdit");
		break;
	case ED_CLAN:
		sprintf(buf, "cEdit");
		break;
	case ED_CMD:
		sprintf(buf, "cmdEdit");
		break;
	case ED_SKILL:
		sprintf(buf, "skEdit");
		break;
	case ED_GROUP:
		sprintf(buf, "grEdit");
		break;
	case ED_RACE:
		sprintf(buf, "raEdit");
		break;
	case ED_CLASS:
		sprintf(buf, "clEdit");
		break;
	case ED_DEITY:
		strcpy(buf, "DEdit");
		break;
	default:
		sprintf(buf, " ");
		break;
	}
	return buf;
}

char *olc_ed_name_long(CHAR_DATA * ch)
{
	static char buf[50];

	if (!ch->desc)
		return "Switched";

	buf[0] = '\0';
	switch (ch->desc->editor)
	{
	case ED_AREA:
		sprintf(buf, "area");
		break;
	case ED_ROOM:
		sprintf(buf, "room");
		break;
	case ED_OBJECT:
		sprintf(buf, "object");
		break;
	case ED_MOBILE:
		sprintf(buf, "mobile");
		break;
	case ED_MPCODE:
		sprintf(buf, "mobile program");
		break;
	case ED_OPCODE:
		sprintf(buf, "object program");
		break;
	case ED_RPCODE:
		sprintf(buf, "room program");
		break;
	case ED_HELP:
		sprintf(buf, "help");
		break;
	case ED_SOCIAL:
		sprintf(buf, "social");
		break;
	case ED_CLAN:
		sprintf(buf, "clan");
		break;
	case ED_CMD:
		sprintf(buf, "command");
		break;
	case ED_SKILL:
		sprintf(buf, "skill");
		break;
	case ED_GROUP:
		sprintf(buf, "group");
		break;
	case ED_RACE:
		sprintf(buf, "race");
		break;
	case ED_CLASS:
		sprintf(buf, "class");
		break;
	case ED_DEITY:
		sprintf(buf, "deity");
		break;
	default:
		break;
	}
	return buf;
}

char *olc_ed_vnum(CHAR_DATA * ch)
{
	AREA_DATA *pArea;
	ROOM_INDEX_DATA *pRoom;
	OBJ_INDEX_DATA *pObj;
	MOB_INDEX_DATA *pMob;
	PROG_CODE *pMprog;
	PROG_CODE *pOprog;
	PROG_CODE *pRprog;
	HELP_DATA *pHelp;
	CLAN_DATA *pClan;
	SOCIAL_DATA *pSocial;
	CMD_DATA *pCmd;
	SKILL_DATA *pSkill;
	GROUP_DATA *pGroup;
	RACE_DATA *pRace;
	CLASS_DATA *pClass;
	DEITY_DATA *pDeity;
	static char buf[MIL];

	buf[0] = '\0';
	switch (ch->desc->editor)
	{
	case ED_AREA:
		pArea = (AREA_DATA *) ch->desc->pEdit;
		sprintf(buf, "%d", pArea ? pArea->vnum : 0);
		break;
	case ED_ROOM:
		pRoom = ch->in_room;
		sprintf(buf, "%ld", pRoom ? pRoom->vnum : 0);
		break;
	case ED_OBJECT:
		pObj = (OBJ_INDEX_DATA *) ch->desc->pEdit;
		sprintf(buf, "%ld", pObj ? pObj->vnum : 0);
		break;
	case ED_MOBILE:
		pMob = (MOB_INDEX_DATA *) ch->desc->pEdit;
		sprintf(buf, "%ld", pMob ? pMob->vnum : 0);
		break;
	case ED_MPCODE:
		pMprog = (PROG_CODE *) ch->desc->pEdit;
		sprintf(buf, "%ld", pMprog ? pMprog->vnum : 0);
		break;
	case ED_OPCODE:
		pOprog = (PROG_CODE *) ch->desc->pEdit;
		sprintf(buf, "%ld", pOprog ? pOprog->vnum : 0);
		break;
	case ED_RPCODE:
		pRprog = (PROG_CODE *) ch->desc->pEdit;
		sprintf(buf, "%ld", pRprog ? pRprog->vnum : 0);
		break;
	case ED_HELP:
		pHelp = (HELP_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pHelp ? pHelp->keyword : "");
		break;
	case ED_SOCIAL:
		pSocial = (SOCIAL_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pSocial ? pSocial->name : "");
		break;
	case ED_CLAN:
		pClan = (CLAN_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pClan ? pClan->name : "");
		break;
	case ED_CMD:
		pCmd = (CMD_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pCmd ? pCmd->name : "");
		break;
	case ED_SKILL:
		pSkill = (SKILL_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pSkill ? pSkill->name : "");
		break;
	case ED_GROUP:
		pGroup = (GROUP_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pGroup ? pGroup->name : "");
		break;
	case ED_RACE:
		pRace = (RACE_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pRace ? pRace->name : "");
		break;
	case ED_CLASS:
		pClass = (CLASS_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pClass ? pClass->name : "");
		break;
	case ED_DEITY:
		pDeity = (DEITY_DATA *) ch->desc->pEdit;
		sprintf(buf, "%s", pDeity ? pDeity->name : "");
		break;
	default:
		sprintf(buf, " ");
		break;
	}

	return buf;
}

void stop_editing(void *OLC)
{
	DESCRIPTOR_DATA *d;

	for (d = descriptor_first; d != NULL; d = d->next)
	{
		if (d->pEdit == NULL || d->character == NULL)
			continue;

		if (d->pEdit == (void *) OLC)
			edit_done(d->character);
	}
	return;
}

const struct olc_comm_type *get_olc_table(int editor)
{
	switch (editor)
	{
	case ED_MOBILE:
		return mob_olc_comm_table;
	case ED_OBJECT:
		return obj_olc_comm_table;
	case ED_ROOM:
		return room_olc_comm_table;
	case ED_AREA:
		return area_olc_comm_table;
	case ED_MPCODE:
		return mprog_olc_comm_table;
	case ED_OPCODE:
		return oprog_olc_comm_table;
	case ED_RPCODE:
		return rprog_olc_comm_table;
	case ED_HELP:
		return help_olc_comm_table;
	case ED_SOCIAL:
		return social_olc_comm_table;
	case ED_CLAN:
		return clan_olc_comm_table;
	case ED_CMD:
		return cmd_olc_comm_table;
	case ED_SKILL:
		return skill_olc_comm_table;
	case ED_GROUP:
		return group_olc_comm_table;
	case ED_RACE:
		return race_olc_comm_table;
	case ED_CLASS:
		return class_olc_comm_table;
	case ED_DEITY:
		return deity_olc_comm_table;
	}
	return NULL;
}

void show_olc_cmds(CHAR_DATA * ch)
{
	char buf[MSL];
	char buf1[MSL];
	int cmd;
	int col;
	const struct olc_comm_type *table;

	buf1[0] = '\0';
	col = 0;

	table = get_olc_table(ch->desc->editor);

	if (table == NULL)
	{
		bugf("table NULL, editor %d", ch->desc->editor);
		return;
	}

	for (cmd = 0; table[cmd].name != NULL; cmd++)
	{
		sprintf(buf, "%-15.15s", table[cmd].name);
		strcat(buf1, buf);
		if (++col % 5 == 0)
			strcat(buf1, "\n\r");
	}

	if (col % 5 != 0)
		strcat(buf1, "\n\r");

	chprint(ch, buf1);
	return;
}

/*****************************************************************************
 Name:		show_commands
 Purpose:	Display all olc commands.
 Called by:	olc interpreters.
 ****************************************************************************/
bool show_commands(CHAR_DATA * ch, char *argument)
{
	show_olc_cmds(ch);
	return FALSE;
}

/*****************************************************************************
 *                           Interpreter Tables.                             *
 *****************************************************************************/
const struct olc_comm_type mob_olc_comm_table[] = {
	{"name", (void *) &xMob.player_name, olced_str, NULL},
	{"short", (void *) &xMob.short_descr, olced_str, NULL},
	{"long", (void *) &xMob.long_descr, olced_str_line, NULL},
	{"desc", (void *) &xMob.description, olced_desc, NULL},

	{"level", (void *) &xMob.level, olced_number,
	 (const void *) validate_level},
	{"align", (void *) &xMob.alignment, olced_number,
	 (const void *) validate_align},
	{"group", (void *) &xMob.group, olced_olded, (const void *) medit_group},
	{"imm", (void *) &xMob.imm_flags, olced_flag, (const void *) imm_flags},
	{"res", (void *) &xMob.res_flags, olced_flag, (const void *) res_flags},
	{"vuln", (void *) &xMob.vuln_flags, olced_flag, (const void *) vuln_flags},
	{"act", (void *) &xMob.act, olced_flag, (const void *) act_flags},

	{"affect", (void *) &xMob.affected_by, olced_flag,
	 (const void *) affect_flags},
	{"off", (void *) &xMob.off_flags, olced_flag, (const void *) off_flags},
	{"form", (void *) &xMob.form, olced_flag, (const void *) form_flags},
	{"parts", (void *) &xMob.parts, olced_flag, (const void *) part_flags},
	{"shop", (void *) &xMob, olced_shop, NULL},
	{"create", NULL, olced_olded, (const void *) medit_create},
	{"delete", NULL, olced_olded, (const void *) medit_delete},
	{"material", (void *) &xMob.material, olced_str, NULL},
	{"addprog", NULL, olced_olded, (const void *) medit_addmprog},
	{"delprog", NULL, olced_olded, (const void *) medit_delmprog},
	{"spec", (void *) &xMob.spec_fun, olced_spec, NULL},
	{"sex", (void *) &xMob.sex, olced_flag, (const void *) sex_flags},
	{"size", (void *) &xMob.size, olced_flag, (const void *) size_flags},

	{"startpos", (void *) &xMob.start_pos, olced_flag,
	 (const void *) position_flags},
	{"defaultpos", (void *) &xMob.default_pos, olced_flag,
	 (const void *) position_flags},
	{"damtype", (void *) &xMob.dam_type, olced_poslookup,
	 (const void *) attack_lookup},
	{"race", (void *) &xMob, olced_race, NULL},
	{"armor", (void *) &xMob, olced_ac, NULL},
	{"hitdice", (void *) &xMob.hit[0], olced_dice, NULL},
	{"manadice", (void *) &xMob.mana[0], olced_dice, NULL},
	{"damdice", (void *) &xMob.damage[0], olced_dice, NULL},
	{"hitroll", (void *) &xMob.hitroll, olced_number, NULL},
	{"wealth", (void *) &xMob.wealth, olced_number_long, NULL},
	{"show", NULL, olced_olded, (const void *) medit_show},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type obj_olc_comm_table[] = {
	{"show", NULL, olced_olded, (const void *) oedit_show},
	{"create", NULL, olced_olded, (const void *) oedit_create},
	{"name", (void *) &xObj.name, olced_str, NULL},
	{"short", (void *) &xObj.short_descr, olced_str, NULL},
	{"long", (void *) &xObj.description, olced_str, NULL},
	{"addaffect", NULL, olced_olded, (const void *) oedit_addaffect},
	{"addapply", NULL, olced_olded, (const void *) oedit_addapply},
	{"delaffect", NULL, olced_olded, (const void *) oedit_delaffect},
	{"v0", NULL, olced_value, (const void *) 0},
	{"v1", NULL, olced_value, (const void *) 1},
	{"v2", NULL, olced_value, (const void *) 2},
	{"v3", NULL, olced_value, (const void *) 3},
	{"v4", NULL, olced_value, (const void *) 4},
	{"material", (void *) &xObj.material, olced_str, NULL},
	{"weight", (void *) &xObj.weight, olced_number, NULL},
	{"cost", (void *) &xObj.cost, olced_number_long, NULL},

	{"ed", (void *) &xObj.first_extra_descr, olced_ed,
	 (const void *) &xObj.last_extra_descr},
	{"delete", NULL, olced_olded, (const void *) oedit_delete},

	{"extra", (void *) &xObj.extra_flags, olced_flag,
	 (const void *) extra_flags},
	{"wear", (void *) &xObj.wear_flags, olced_flag,
	 (const void *) wear_flags},
	{"type", (void *) &xObj.item_type, olced_flag, (const void *) type_flags},

	{"level", (void *) &xObj.level, olced_number,
	 (const void *) validate_level},
	{"addprog", NULL, olced_olded, (void *) oedit_addoprog},
	{"delprog", NULL, olced_olded, (void *) oedit_deloprog},
	{"condition", (void *) &xObj.condition, olced_number, NULL},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type room_olc_comm_table[] = {
	{"show", NULL, olced_olded, (const void *) redit_show},
	{"create", NULL, olced_olded, (const void *) redit_create},
	{"name", (void *) &xRoom.name, olced_str, NULL},
	{"desc", (void *) &xRoom.description, olced_desc, NULL},

	{"ed", (void *) &xRoom.first_extra_descr, olced_ed,
	 (const void *) &xRoom.last_extra_descr},
	{"format", NULL, olced_olded, (const void *) redit_format},
	{"north", NULL, olced_direction, (const void *) DIR_NORTH},
	{"south", NULL, olced_direction, (const void *) DIR_SOUTH},
	{"east", NULL, olced_direction, (const void *) DIR_EAST},
	{"west", NULL, olced_direction, (const void *) DIR_WEST},
	{"up", NULL, olced_direction, (const void *) DIR_UP},
	{"down", NULL, olced_direction, (const void *) DIR_DOWN},
	{"mreset", NULL, olced_olded, (const void *) redit_mreset},
	{"oreset", NULL, olced_olded, (const void *) redit_oreset},
	{"mshow", NULL, olced_olded, (const void *) redit_mshow},
	{"oshow", NULL, olced_olded, (const void *) redit_oshow},
	{"clan", NULL, olced_olded, (const void *) redit_clan},
	{"purge", NULL, olced_docomm, (const void *) do_purge},
	{"heal", (void *) &xRoom.heal_rate, olced_number, NULL},
	{"mana", (void *) &xRoom.mana_rate, olced_number, NULL},
	{"owner", (void *) &xRoom.owner, olced_str, NULL},
	{"room", (void *) &xRoom.room_flags, olced_flag, (const void *) room_flags},
	{"olist", NULL, olced_olded, (const void *) redit_olist},
	{"mlist", NULL, olced_olded, (const void *) redit_mlist},
	{"rlist", NULL, olced_olded, (const void *) redit_rlist},
	{"sector", (void *) &xRoom.sector_type, olced_flag,
	 (const void *) sector_flags},
	{"addprog", NULL, olced_olded, (void *) redit_addrprog},
	{"delprog", NULL, olced_olded, (void *) redit_delrprog},
	{"delete", NULL, olced_olded, (const void *) redit_delete},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type area_olc_comm_table[] = {
	{"show", NULL, olced_olded, (const void *) aedit_show},
	{"create", NULL, olced_olded, (const void *) aedit_create},
	{"name", (void *) &xArea.name, olced_str, NULL},
	{"file", NULL, olced_olded, (const void *) aedit_file},
	{"age", (void *) &xArea.age, olced_number, NULL},
	{"reset", NULL, olced_olded, (const void *) aedit_reset},
	{"security", (void *) &xArea.security, olced_number, NULL},
	{"builder", NULL, olced_olded, (const void *) aedit_builder},
	{"vnum", NULL, olced_olded, (const void *) aedit_vnum},
	{"lvnum", NULL, olced_olded, (const void *) aedit_lvnum},
	{"uvnum", NULL, olced_olded, (const void *) aedit_uvnum},
	{"credits", (void *) &xArea.credits, olced_str, NULL},
	{"flag", (void *) &xArea.area_flags, olced_flag, (const void *) area_flags},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type mprog_olc_comm_table[] = {
	{"create", NULL, olced_olded, (const void *) mpedit_create},
	{"code", (void *) &xMProg.code, olced_desc, NULL},
	{"show", NULL, olced_olded, (const void *) mpedit_show},
	{"list", NULL, olced_olded, (const void *) mpedit_list},
	{"delete", NULL, olced_olded, (const void *) mpedit_delete},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type oprog_olc_comm_table[] = {
	{"create", NULL, olced_olded, (const void *) opedit_create},
	{"code", (void *) &xOProg.code, olced_desc, NULL},
	{"show", NULL, olced_olded, (const void *) opedit_show},
	{"list", NULL, olced_olded, (const void *) opedit_list},
	{"delete", NULL, olced_olded, (const void *) opedit_delete},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type rprog_olc_comm_table[] = {
	{"create", NULL, olced_olded, (const void *) rpedit_create},
	{"code", (void *) &xRProg.code, olced_desc, NULL},
	{"show", NULL, olced_olded, (const void *) rpedit_show},
	{"list", NULL, olced_olded, (const void *) rpedit_list},
	{"delete", NULL, olced_olded, (const void *) rpedit_delete},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type help_olc_comm_table[] = {
	{"show", NULL, olced_olded, (const void *) hedit_show},
	{"make", NULL, olced_olded, (const void *) hedit_new},
	{"text", (void *) &xHelp.text, olced_desc, NULL},

	{"level", (void *) &xHelp.level, olced_number,
	 (const void *) validate_level},
	{"keywords", (void *) &xHelp.keyword, olced_str, NULL},
	{"delete", NULL, olced_olded, (const void *) hedit_delete},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type clan_olc_comm_table[] = {
	{"show", NULL, olced_olded, (const void *) cedit_show},
	{"name", (void *) &xClan.name, olced_str, NULL},
	{"who", (void *) &xClan.who_name, olced_str, NULL},
	{"independent", (void *) &xClan.independent, olced_bool, NULL},
	{"hall", (void *) &xClan.hall, olced_number, NULL},
	{"delete", NULL, olced_olded, (const void *) cedit_delete},
	{"create", NULL, olced_olded, (const void *) cedit_create},
	{"rank", NULL, olced_olded, (const void *) cedit_rank},
	{"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},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type social_olc_comm_table[] = {
	{"show", NULL, olced_olded, (const void *) sedit_show},
	{"name", (void *) &xSoc.name, olced_str, NULL},
	{"create", NULL, olced_olded, (const void *) sedit_create},
	{"delete", NULL, olced_olded, (const void *) sedit_delete},
	{"cnoarg", (void *) &xSoc.char_no_arg, olced_str, NULL},
	{"onoarg", (void *) &xSoc.others_no_arg, olced_str, NULL},
	{"cfound", (void *) &xSoc.char_found, olced_str, NULL},
	{"ofound", (void *) &xSoc.others_found, olced_str, NULL},
	{"vfound", (void *) &xSoc.vict_found, olced_str, NULL},
	{"cself", (void *) &xSoc.char_auto, olced_str, NULL},
	{"oself", (void *) &xSoc.others_auto, olced_str, NULL},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

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},
	{"rearrange", NULL, olced_olded, (void *) cmdedit_rearrange},

	{"level", (void *) &xCmd.level, olced_number,
	 (const void *) validate_level},
	{"position", (void *) &xCmd.position, olced_flag,
	 (const void *) position_flags},
	{"log", (void *) &xCmd.log, olced_flag, (const void *) log_flags},
	{"fShow", (void *) &xCmd.show, olced_bool, NULL},
	{"dofun", NULL, olced_olded, (const void *) cmdedit_dofun},
	{"delete", NULL, olced_olded, (const void *) cmdedit_delete},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type skill_olc_comm_table[] = {
	{"show", NULL, olced_olded, (const void *) skedit_show},
	{"create", NULL, olced_olded, (const void *) skedit_create},
	{"name", (void *) &xSkill.name, olced_str, NULL},
	{"levels", NULL, olced_olded, (const void *) skedit_levels},
	{"ratings", NULL, olced_olded, (const void *) skedit_ratings},
	{"spellfun", NULL, olced_olded, (const void *) skedit_spellfun},

	{"target", (void *) &xSkill.target, olced_flag,
	 (const void *) target_flags},
	{"minpos", (void *) &xSkill.minimum_position, olced_flag,
	 (const void *) position_flags},
	{"gsn", NULL, olced_olded, (const void *) skedit_gsn},
	{"minmana", (void *) &xSkill.min_mana, olced_number, NULL},
	{"beats", (void *) &xSkill.beats, olced_number, NULL},
	{"damnoun", (void *) &xSkill.noun_damage, olced_str, NULL},
	{"msgoff", (void *) &xSkill.msg_off, olced_str, NULL},
	{"msgobj", (void *) &xSkill.msg_obj, olced_str, NULL},
	{"delete", NULL, olced_olded, (const void *) skedit_delete},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type group_olc_comm_table[] = {
	{"show", NULL, olced_olded, (const void *) gredit_show},
	{"create", NULL, olced_olded, (const void *) gredit_create},

	{"name", (void *) &xGroup.name, olced_str,
	 (const void *) validate_groupname},
	{"ratings", NULL, olced_olded, (const void *) gredit_ratings},
	{"spells", NULL, olced_olded, (const void *) gredit_spells},
	{"delete", NULL, olced_olded, (const void *) gredit_delete},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type race_olc_comm_table[] = {
	{"create", NULL, olced_olded, (const void *) raedit_create},
	{"delete", NULL, olced_olded, (const void *) raedit_delete},
	{"show", NULL, olced_olded, (const void *) raedit_show},
	{"name", (void *) &xRace.name, olced_str, NULL},
	{"act", (void *) &xRace.act, olced_flag, (const void *) act_flags},
	{"aff", (void *) &xRace.aff, olced_flag, (const void *) affect_flags},
	{"form", (void *) &xRace.form, olced_flag, (const void *) form_flags},
	{"off", (void *) &xRace.off, olced_flag, (const void *) off_flags},
	{"imm", (void *) &xRace.imm, olced_flag, (const void *) imm_flags},
	{"res", (void *) &xRace.res, olced_flag, (const void *) res_flags},
	{"vuln", (void *) &xRace.vuln, olced_flag, (const void *) vuln_flags},
	{"parts", (void *) &xRace.parts, olced_flag, (const void *) part_flags},
	{"pcrace", (void *) &xRace.pc_race, olced_bool, NULL},
	{"points", (void *) &xRace.points, olced_number, NULL},
	{"list", NULL, olced_olded, (const void *) raedit_list},
	{"stats", NULL, olced_olded, (const void *) raedit_stats},
	{"mstats", NULL, olced_olded, (const void *) raedit_mstats},
	{"skills", NULL, olced_olded, (const void *) raedit_skills},
	{"whoname", (void *) &xRace.who_name, olced_str, NULL},
	{"size", (void *) &xRace.size, olced_flag, (const void *) size_flags},
	{"classx", NULL, olced_olded, (const void *) raedit_classx},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type class_olc_comm_table[] = {
	{"create", NULL, olced_olded, (const void *) cledit_create},
	{"delete", NULL, olced_olded, (const void *) cledit_delete},
	{"show", NULL, olced_olded, (const void *) cledit_show},

	{"name", (void *) &xClass.name, olced_str,
	 (const void *) validate_classname},
	{"who", (void *) &xClass.who_name, olced_str,
	 (const void *) validate_whoname},
	{"prime", NULL, olced_olded, (const void *) cledit_prime},

	{"weapon", (void *) &xClass.weapon, olced_vnum,
	 (const void *) validate_weapon},
	{"adept", (void *) &xClass.skill_adept, olced_number,
	 (const void *) validate_adept},
	{"thac0", (void *) &xClass.thac0_00, olced_number, NULL},
	{"thac32", (void *) &xClass.thac0_32, olced_number, NULL},

	{"hpmin", (void *) &xClass.hp_min, olced_number,
	 (const void *) validate_hmv},
	{"hpmax", (void *) &xClass.hp_max, olced_number,
	 (const void *) validate_hmv},
	{"fmana", (void *) &xClass.fMana, olced_bool, NULL},
	{"guilds", NULL, olced_olded, (const void *) cledit_guilds},

	{"basegroup", (void *) &xClass.base_group, olced_str,
	 (const void *) validate_group},
	{"default", (void *) &xClass.default_group, olced_str,
	 (const void *) validate_group},
	{"skill", NULL, olced_olded, (const void *) cledit_skill},
	{"commands", NULL, olced_olded, (const void *) show_commands},
	{"?", NULL, olced_olded, (const void *) show_help},
	{"version", NULL, olced_olded, (const void *) show_version},
	{NULL, NULL, NULL, NULL}
};

const struct olc_comm_type deity_olc_comm_table[] = {
	{"show", NULL, olced_olded, (void *) dedit_show},
	{"create", NULL, olced_olded, (void *) dedit_create},
	{"delete", NULL, olced_olded, (void *) dedit_delete},
	{"list", NULL, olced_olded, (void *) dedit_list},
	{"name", (void *) &xDeity.name, olced_str, NULL},
	{"desc", (void *) &xDeity.desc, olced_str, NULL},
	{"skill", (void *) &xDeity.skillname, olced_str, NULL},
	{"commands", NULL, olced_olded, (void *) show_commands},
	{"?", NULL, olced_olded, (void *) show_help},
	{"version", NULL, olced_olded, (void *) show_version},
	{NULL, NULL, NULL, NULL}
};

/*****************************************************************************
 *                          End Interpreter Tables.                          *
 *****************************************************************************/

/*****************************************************************************
 Name:		get_area_data
 Purpose:	Returns pointer to area with given vnum.
 Called by:	do_aedit(olc.c).
 ****************************************************************************/
AREA_DATA *get_area_data(int vnum)
{
	AREA_DATA *pArea;

	for (pArea = area_first; pArea; pArea = pArea->next)
	{
		if (pArea->vnum == vnum)
			return pArea;
	}

	return 0;
}

/*****************************************************************************
 Name:		edit_done
 Purpose:	Resets builder information on completion.
 Called by:	aedit, redit, oedit, medit(olc.c)
 ****************************************************************************/
bool edit_done(CHAR_DATA * ch)
{
	if (ch->desc->editor > 0)
	{
		act("$n stop using the $t editor.", ch, olc_ed_name_long(ch), NULL,
			TO_ROOM);
		act("You stop using the $t editor.", ch, olc_ed_name_long(ch), NULL,
			TO_CHAR);
	}

	ch->desc->pEdit = NULL;
	ch->desc->editor = 0;
	return FALSE;
}

/*****************************************************************************
 *                              Interpreters.                                *
 *****************************************************************************/

bool process_olc_command(CHAR_DATA * ch, const char *argument,
						 const struct olc_comm_type * table)
{
	char arg[MIL];
	AREA_DATA *tArea, *pArea;
	MOB_INDEX_DATA *pMob;
	OBJ_INDEX_DATA *pObj;
	ROOM_INDEX_DATA *pRoom;
	PROG_CODE *pMProg;
	PROG_CODE *pOProg;
	PROG_CODE *pRProg;
	HELP_DATA *pHelp;
	SOCIAL_DATA *pSoc;
	CLAN_DATA *pClan;
	CMD_DATA *pCmd;
	SKILL_DATA *pSkill;
	GROUP_DATA *pGroup;
	RACE_DATA *pRace;
	CLASS_DATA *pClass;
	DEITY_DATA *pDeity;
	int temp;
	void *puntero;
	const char *logline = argument;

	argument = one_argument(argument, arg);

	for (temp = 0; table[temp].name; temp++)
	{
		if (LOWER(arg[0]) == LOWER(table[temp].name[0])
			&& !str_prefix(arg, table[temp].name))
		{
			if ((!IS_NPC(ch) && IS_SET(ch->act, PLR_LOG)) || fLogAll)
			{
				sprintf(log_buf, "Log %s: %s", ch->name, logline);
				log_string(log_buf);
			}

			if (ch->desc != NULL && ch->desc->snoop_by != NULL)
			{
				write_to_buffer(ch->desc->snoop_by, "% ", 2);
				write_to_buffer(ch->desc->snoop_by, logline, 0);
				write_to_buffer(ch->desc->snoop_by, "\n\r", 2);
			}

			switch (ch->desc->editor)
			{
			case ED_MOBILE:
				EDIT_MOB(ch, pMob);
				tArea = pMob->area;
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xMob + (int) pMob);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter) && tArea)
					SET_BIT(tArea->area_flags, AREA_CHANGED);
				return TRUE;
				break;
			case ED_OBJECT:
				EDIT_OBJ(ch, pObj);
				tArea = pObj->area;
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xObj + (int) pObj);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter) && tArea != NULL)
					SET_BIT(tArea->area_flags, AREA_CHANGED);
				return TRUE;
				break;
			case ED_ROOM:
				EDIT_ROOM(ch, pRoom);
				tArea = pRoom->area;
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xRoom + (int) pRoom);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter) && tArea != NULL)
					SET_BIT(tArea->area_flags, AREA_CHANGED);
				return TRUE;
				break;
			case ED_AREA:
				EDIT_AREA(ch, pArea);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xArea + (int) pArea);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					SET_BIT(pArea->area_flags, AREA_CHANGED);
				return TRUE;
				break;
			case ED_MPCODE:
				EDIT_MPCODE(ch, pMProg);
				tArea = get_vnum_area(pMProg->vnum);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xMProg + (int) pMProg);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					SET_BIT(tArea->area_flags, AREA_CHANGED);
				return TRUE;
				break;
			case ED_OPCODE:
				EDIT_OPCODE(ch, pOProg);
				tArea = get_vnum_area(pOProg->vnum);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xOProg + (int) pOProg);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					SET_BIT(tArea->area_flags, AREA_CHANGED);
				return TRUE;
				break;
			case ED_RPCODE:
				EDIT_RPCODE(ch, pRProg);
				tArea = get_vnum_area(pRProg->vnum);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xRProg + (int) pRProg);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					SET_BIT(tArea->area_flags, AREA_CHANGED);
				return TRUE;
				break;
			case ED_HELP:
				EDIT_HELP(ch, pHelp);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xHelp + (int) pHelp);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_helps();
				return TRUE;
				break;
			case ED_SOCIAL:
				EDIT_SOCIAL(ch, pSoc);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xSoc + (int) pSoc);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_social_table();
				return TRUE;
				break;
			case ED_CLAN:
				EDIT_CLAN(ch, pClan);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xClan + (int) pClan);
				else
					puntero = NULL;

				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_clans();
				return TRUE;
				break;
			case ED_DEITY:
				EDIT_DEITY(ch, pDeity);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument - (int) &xDeity +
								  (int) pDeity);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_deities();
				return TRUE;
				break;
			case ED_CMD:
				EDIT_CMD(ch, pCmd);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument -
								  (int) &xCmd + (int) pCmd);
				else
					puntero = NULL;

				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_commands();
				return TRUE;
				break;
			case ED_SKILL:
				EDIT_SKILL(ch, pSkill);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument - (int) &xSkill +
								  (int) pSkill);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_skills();
				return TRUE;
				break;
			case ED_GROUP:
				EDIT_GROUP(ch, pGroup);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument - (int) &xGroup +
								  (int) pGroup);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_groups();
				return TRUE;
				break;
			case ED_RACE:
				EDIT_RACE(ch, pRace);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument - (int) &xRace +
								  (int) pRace);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_races();
				return TRUE;
				break;
			case ED_CLASS:
				EDIT_CLASS(ch, pClass);
				if (table[temp].argument)
					puntero =
						(void *) ((int) table[temp].argument - (int) &xClass +
								  (int) pClass);
				else
					puntero = NULL;
				if ((*table[temp].function)
					(table[temp].name, ch, argument, puntero,
					 table[temp].parameter))
					save_classes();
				return TRUE;
				break;
			}
		}
	}

	return FALSE;
}

/* Area Interpreter, called by do_aedit. */
void aedit(CHAR_DATA * ch, char *argument)
{
	AREA_DATA *pArea;

	EDIT_AREA(ch, pArea);

	if (!IS_BUILDER(ch, pArea))
	{
		chprintln(ch, "AEdit:  Insufficient security to modify area.");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		aedit_show(ch, argument);
		return;
	}

	if (!process_olc_command(ch, argument, area_olc_comm_table))
		interpret(ch, argument);
	return;
}

/* Room Interpreter, called by do_redit. */
void redit(CHAR_DATA * ch, char *argument)
{
	AREA_DATA *pArea;
	ROOM_INDEX_DATA *pRoom;

	EDIT_ROOM(ch, pRoom);
	pArea = pRoom->area;

	if (!IS_BUILDER(ch, pArea))
	{
		chprintln(ch, "REdit:  Insufficient security to modify room.");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		redit_show(ch, argument);
		return;
	}

	if (!process_olc_command(ch, argument, room_olc_comm_table))
		interpret(ch, argument);
	return;
}

/* Object Interpreter, called by do_oedit. */
void oedit(CHAR_DATA * ch, char *argument)
{
	AREA_DATA *pArea;
	OBJ_INDEX_DATA *pObj;

	EDIT_OBJ(ch, pObj);
	pArea = pObj->area;

	if (!IS_BUILDER(ch, pArea))
	{
		chprintln(ch, "OEdit: Insufficient security to modify area.");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		oedit_show(ch, argument);
		return;
	}

	if (!process_olc_command(ch, argument, obj_olc_comm_table))
		interpret(ch, argument);
	return;
}

/* Mobile Interpreter, called by do_medit. */
void medit(CHAR_DATA * ch, char *argument)
{
	AREA_DATA *pArea;
	MOB_INDEX_DATA *pMob;

	EDIT_MOB(ch, pMob);
	pArea = pMob->area;

	if (!IS_BUILDER(ch, pArea))
	{
		chprintln(ch, "mEdit: Insufficient security to modify area.");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		medit_show(ch, argument);
		return;
	}

	if (!process_olc_command(ch, argument, mob_olc_comm_table))
		interpret(ch, argument);
	return;
}

void cedit(CHAR_DATA * ch, char *argument)
{
	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		cedit_show(ch, argument);
		return;
	}

	if (!process_olc_command(ch, argument, clan_olc_comm_table))
		interpret(ch, argument);
	return;
}

void cmdedit(CHAR_DATA * ch, char *argument)
{
	if (get_trust(ch) < MAX_LEVEL - 5)
	{
		chprintln(ch, "Insuffecient security to modify command data");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		cmdedit_show(ch, argument);
		return;
	}
	if (!process_olc_command(ch, argument, cmd_olc_comm_table))
		interpret(ch, argument);
	return;
}

void skedit(CHAR_DATA * ch, char *argument)
{
	if (get_trust(ch) < MAX_LEVEL - 5)
	{
		chprintln(ch, "Insuffecient security to modify race data");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		skedit_show(ch, argument);
		return;
	}
	if (!process_olc_command(ch, argument, skill_olc_comm_table))
		interpret(ch, argument);
	return;
}

void gredit(CHAR_DATA * ch, char *argument)
{
	if (get_trust(ch) < MAX_LEVEL - 5)
	{
		chprintln(ch, "Insuffecient security to modify group data");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		gredit_show(ch, argument);
		return;
	}
	if (!process_olc_command(ch, argument, group_olc_comm_table))
		interpret(ch, argument);
	return;
}

void raedit(CHAR_DATA * ch, char *argument)
{
	if (get_trust(ch) < MAX_LEVEL - 5)
	{
		chprintln(ch, "Insuffecient security to modify race data");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		raedit_show(ch, argument);
		return;
	}

	if (!process_olc_command(ch, argument, race_olc_comm_table))
		interpret(ch, argument);
	return;
}

void cledit(CHAR_DATA * ch, char *argument)
{
	if (get_trust(ch) < MAX_LEVEL - 5)
	{
		chprintln(ch, "Insuffecient security to modify class data");
		edit_done(ch);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (emptystring(argument))
	{
		cledit_show(ch, argument);
		return;
	}

	if (!process_olc_command(ch, argument, class_olc_comm_table))
		interpret(ch, argument);
	return;
}

const struct editor_cmd_type editor_table[] = {
/*  {   command		function	}, */

	{"area", do_aedit},
	{"room", do_redit},
	{"object", do_oedit},
	{"mobile", do_medit},
	{"mpcode", do_mpedit},
	{"hedit", do_hedit},
	{"social", do_sedit},
	{"clan", do_cedit},
	{"command", do_cmdedit},
	{"skill", do_skedit},
	{"group", do_gredit},
	{"race", do_raedit},
	{"class", do_cledit},
	{"deity", do_dedit},
	{NULL, 0}
};

/* Entry point for all editors. */
CH_CMD(do_olc)
{
	char command[MAX_INPUT_LENGTH];
	int cmd;

	if (IS_NPC(ch))
		return;

	argument = one_argument(argument, command);

	if (command[0] == '\0')
	{
		do_oldhelp(ch, "olc");
		return;
	}

	/* Search Table and Dispatch Command. */
	for (cmd = 0; editor_table[cmd].name != NULL; cmd++)
	{
		if (!str_prefix(command, editor_table[cmd].name))
		{
			(*editor_table[cmd].do_fun) (ch, argument);
			return;
		}
	}

	/* Invalid command, send help. */
	do_oldhelp(ch, "olc");
	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)
		return &skill_table[skill];

	return &skill_table[0];
}

GROUP_DATA *get_group_data(int group)
{
	if (group > -1 && group < maxGroup)
		return &group_table[group];

	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)
		return &class_table[Class];

	return &class_table[0];
}

void clean_area_links(AREA_DATA * target)
{
	vnum_t vnum;
	char buf[20];

	for (vnum = target->min_vnum; vnum <= target->max_vnum; vnum++)
	{
		if (get_prog_index(vnum, PRG_MPROG) != NULL)
		{
			sprintf(buf, "%ld", vnum);
			if (!mpedit_delete(NULL, buf))
				bugf("Unable to delete Mprog %ld", vnum);
		}
		if (get_prog_index(vnum, PRG_OPROG) != NULL)
		{
			sprintf(buf, "%ld", vnum);
			if (!opedit_delete(NULL, buf))
				bugf("Unable to delete Oprog %ld", vnum);
		}
		if (get_prog_index(vnum, PRG_RPROG) != NULL)
		{
			sprintf(buf, "%ld", vnum);
			if (!rpedit_delete(NULL, buf))
				bugf("Unable to delete Rprog %ld", vnum);
		}
		if (get_room_index(vnum) != NULL)
		{
			sprintf(buf, "%ld", vnum);
			if (!redit_delete(NULL, buf))
				bugf("Unable to delete Room %ld", vnum);
		}
		if (get_obj_index(vnum) != NULL)
		{
			sprintf(buf, "%ld", vnum);
			if (!oedit_delete(NULL, buf))
				bugf("Unable to delete Object %ld", vnum);
		}
		if (get_mob_index(vnum) != NULL)
		{
			sprintf(buf, "%ld", vnum);
			if (!medit_delete(NULL, buf))
				bugf("Unable to delete Mobile %ld", vnum);
		}
	}
}

bool vnum_OK(vnum_t lnum, vnum_t hnum)
{
	int i;

	for (i = 0; vnum_table[i].vnum != -1; i++)
	{
		if (vnum_table[i].vnum >= lnum && vnum_table[i].vnum <= hnum)
			return FALSE;
	}
	return TRUE;
}

/* Entry point for editing area_data. */
CH_CMD(do_aedit)
{
	AREA_DATA *pArea;
	int value;
	char arg[MAX_STRING_LENGTH];

	if (IS_NPC(ch))
		return;

	pArea = ch->in_room->area;

	argument = one_argument(argument, arg);

	if (is_number(arg))
	{
		value = atoi(arg);
		if (!(pArea = get_area_data(value)))
		{
			chprintln(ch, "That area vnum does not exist.");
			return;
		}
	}
	else if (!str_cmp(arg, "create"))
	{
		if (ch->pcdata->security < 9)
		{
			chprintln(ch, "AEdit : Seguridad insuficiente para crear area.");
			return;
		}

		aedit_create(ch, "");
		ch->desc->editor = ED_AREA;
		act("$n has entered the area editor.", ch, NULL, NULL, TO_ROOM);
		return;
	}
	else if (!str_cmp(arg, "delete"))
	{
		if (ch->pcdata->security < 9)
		{
			chprintln(ch, "AEdit : Seguridad insuficiente para delete area.");
			return;
		}
		if (!is_number(argument) || !(pArea = get_area_data(atoi(argument))))
		{
			chprintln(ch, "That area vnum does not exist.");
			return;
		}

		if (vnum_OK(pArea->min_vnum, pArea->max_vnum) == FALSE)
		{
			chprintln(ch,
					  "That area contains hard coded vnums and cannot be deleted.");
			return;
		}

		clean_area_links(pArea);
		unlink(pArea->file_name);
		UNLINK(pArea, area_first, area_last, next, prev);
		free_area(pArea);
		do_asave(NULL, "changed");
		chprintln(ch, "Area deleted.");
		return;
	}
	if (!IS_BUILDER(ch, pArea))
	{
		chprintln(ch, "Insuficiente seguridad para editar areas.");
		return;
	}

	edit_start(ch, pArea, ED_AREA);
	return;
}

/* Entry point for editing room_index_data. */
CH_CMD(do_redit)
{
	ROOM_INDEX_DATA *pRoom;
	char arg1[MAX_STRING_LENGTH];

	if (IS_NPC(ch))
		return;

	argument = one_argument(argument, arg1);

	pRoom = ch->in_room;

	if (!str_cmp(arg1, "reset"))	/* redit reset */
	{
		if (!IS_BUILDER(ch, pRoom->area))
		{
			chprintln(ch, "Insufficient security to modify cuartos.");
			return;
		}

		reset_room(pRoom);
		chprintln(ch, "Room reset.");

		return;
	}
	else if (!str_cmp(arg1, "create"))	/* redit create <vnum> */
	{
		if (argument[0] == '\0' || atol(argument) == 0)
		{
			chprintln(ch, "Syntax:  edit room create [vnum]");
			return;
		}

		if (redit_create(ch, argument))	/* pEdit == nuevo cuarto */
		{
			ch->desc->editor = ED_ROOM;
			act("$n has entered the room editor.", ch, NULL, NULL, TO_ROOM);
			char_from_room(ch);
			char_to_room(ch, (ROOM_INDEX_DATA *) ch->desc->pEdit);
			SET_BIT(((ROOM_INDEX_DATA *) ch->desc->pEdit)->area->area_flags,
					AREA_CHANGED);
		}

		return;
	}
	else if (!str_cmp(arg1, "delete"))
	{
		redit_delete(ch, argument);
		return;
	}
	else if (!IS_NULLSTR(arg1))	/* redit <vnum> */
	{
		pRoom = get_room_index(atol(arg1));

		if (!pRoom)
		{
			chprintln(ch, "REdit : cuarto inexistente.");
			return;
		}

		if (!IS_BUILDER(ch, pRoom->area))
		{
			chprintln(ch, "REdit : insuficiente seguridad para editar cuarto.");
			return;
		}

		char_from_room(ch);
		char_to_room(ch, pRoom);
	}

	if (!IS_BUILDER(ch, pRoom->area))
	{
		chprintln(ch, "REdit : Insuficiente seguridad para editar cuartos.");
		return;
	}

	edit_start(ch, pRoom, ED_ROOM);
	return;
}

/* Entry point for editing obj_index_data. */
CH_CMD(do_oedit)
{
	OBJ_INDEX_DATA *pObj;
	AREA_DATA *pArea;
	char arg1[MAX_STRING_LENGTH];
	vnum_t value;

	if (IS_NPC(ch))
		return;

	argument = one_argument(argument, arg1);

	if (is_number(arg1))
	{
		value = atol(arg1);
		if (!(pObj = get_obj_index(value)))
		{
			chprintln(ch, "OEdit:  That vnum does not exist.");
			return;
		}

		if (!IS_BUILDER(ch, pObj->area))
		{
			chprintln(ch, "Insufficient security to modify objetos.");
			return;
		}

		edit_start(ch, pObj, ED_OBJECT);
		return;
	}
	else
	{
		if (!str_cmp(arg1, "create"))
		{
			value = atol(argument);
			if (argument[0] == '\0' || value == 0)
			{
				chprintln(ch, "Syntax:  edit object create [vnum]");
				return;
			}

			pArea = get_vnum_area(value);

			if (!pArea)
			{
				chprintln(ch, "OEdit:  That vnum is not assigned an area.");
				return;
			}

			if (!IS_BUILDER(ch, pArea))
			{
				chprintln(ch, "Insufficient security to modify objetos.");
				return;
			}

			if (oedit_create(ch, argument))
			{
				SET_BIT(pArea->area_flags, AREA_CHANGED);
				ch->desc->editor = ED_OBJECT;
				act("$n has entered the object editor.", ch,
					NULL, NULL, TO_ROOM);
			}
			return;
		}
		else if (!str_cmp(arg1, "delete"))
		{
			oedit_delete(ch, argument);
			return;
		}
	}

	chprintln(ch, "OEdit:  There is no default object to edit.");
	return;
}

/* Entry point for editing mob_index_data. */
CH_CMD(do_medit)
{
	MOB_INDEX_DATA *pMob;
	AREA_DATA *pArea;
	vnum_t value;
	char arg1[MAX_STRING_LENGTH];

	argument = one_argument(argument, arg1);

	if (IS_NPC(ch))
		return;

	if (is_number(arg1))
	{
		value = atol(arg1);
		if (!(pMob = get_mob_index(value)))
		{
			chprintln(ch, "MEdit:  That vnum does not exist.");
			return;
		}

		if (!IS_BUILDER(ch, pMob->area))
		{
			chprintln(ch, "Insufficient security to modify mobs.");
			return;
		}

		edit_start(ch, pMob, ED_MOBILE);
		return;
	}
	else
	{
		if (!str_cmp(arg1, "create"))
		{
			value = atol(argument);
			if (arg1[0] == '\0' || value == 0)
			{
				chprintln(ch, "Syntax:  edit mobile create [vnum]");
				return;
			}

			pArea = get_vnum_area(value);

			if (!pArea)
			{
				chprintln(ch, "MEdit:  That vnum is not assigned an area.");
				return;
			}

			if (!IS_BUILDER(ch, pArea))
			{
				chprintln(ch, "Insufficient security to modify mobs.");
				return;
			}

			if (medit_create(ch, argument))
			{
				SET_BIT(pArea->area_flags, AREA_CHANGED);
				ch->desc->editor = ED_MOBILE;
				act("$n has entered the mobile editor.", ch,
					NULL, NULL, TO_ROOM);
			}
			return;
		}
		else if (!str_cmp(arg1, "delete"))
		{
			medit_delete(ch, argument);
			return;
		}
	}

	chprintln(ch, "MEdit:  There is no default mobile to edit.");
	return;
}

CH_CMD(do_cedit)
{
	CLAN_DATA *pClan;
	int value;
	char arg[MSL];

	if (IS_NPC(ch))
		return;

	pClan = &clan_table[0];

	argument = one_argument(argument, arg);

	if (IS_NULLSTR(arg))
	{
		chprintln(ch, "Syntax: cedit create\n\r        cedit #/clan name");
		return;
	}

	if (is_number(arg))
		value = atoi(arg);
	else
		value = clan_lookup(arg);

	if (value > -1)
	{
		pClan = get_clan_data(value);

		if (!pClan || IS_NULLSTR(pClan->name))
		{
			chprintln(ch, "That clan does not exist.");
			return;
		}

	}
	else if (!str_cmp(arg, "save"))
	{
		save_clans();
		chprintln(ch, "Clan database saved.");
		return;
	}
	else if (!str_cmp(arg, "create"))
	{
		if (ch->pcdata->security < 9)
		{
			chprintln(ch, "cEdit : Insuffecient security to create new clans.");
			return;
		}
		cedit_create(ch, argument);

		return;
	}

	edit_start(ch, pClan, ED_CLAN);
	return;
}

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");
		return;
	}

	if (is_number(arg))
		value = atoi(arg);
	else
		value = command_lookup(arg);

	if (value > -1)
	{
		pCmd = get_cmd_data(value);

		if (!pCmd || IS_NULLSTR(pCmd->name))
		{
			chprintln(ch, "That command does not exist.");
			return;
		}

	}
	else if (!str_cmp(arg, "save"))
	{
		save_commands();
		chprintln(ch, "Command database saved.");
		return;
	}
	else if (!str_cmp(arg, "create"))
	{
		if (ch->pcdata->security < 9)
		{
			chprintln
				(ch, "cmdEdit : Insuffecient security to create new commands.");
			return;
		}

		cmdedit_create(ch, argument);

		return;
	}

	edit_start(ch, pCmd, ED_CMD);

	return;
}

CH_CMD(do_skedit)
{
	SKILL_DATA *pSkill;
	int value;
	char arg[MSL];

	if (IS_NPC(ch))
		return;

	pSkill = &skill_table[0];

	argument = one_argument(argument, arg);

	if (IS_NULLSTR(arg))
	{
		chprintln(ch, "Syntax: skedit make\n\r" "      : skedit save\n\r"
				  "      : skedit #/skill name");
		return;
	}

	if (is_number(arg))
		value = atoi(arg);
	else
		value = skill_lookup(arg);

	if (value > -1)
	{
		pSkill = get_skill_data(value);

		if (!pSkill || IS_NULLSTR(pSkill->name))
		{
			chprintln(ch, "That skill does not exist.");
			return;
		}

	}
	else if (!str_cmp(arg, "save"))
	{
		save_skills();
		chprintln(ch, "Skill database saved.");
		return;
	}
	else if (!str_cmp(arg, "make") || !str_cmp(arg, "create"))
	{
		if (ch->pcdata->security < 9)
		{
			chprintln
				(ch, "skEdit : Insuffecient security to create new skills.");
			return;
		}

		skedit_create(ch, argument);

		return;
	}

	edit_start(ch, pSkill, ED_SKILL);
	return;
}

CH_CMD(do_gredit)
{
	GROUP_DATA *pGroup;
	int value;
	char arg[MSL];

	if (IS_NPC(ch))
		return;

	pGroup = &group_table[0];

	argument = one_argument(argument, arg);

	if (IS_NULLSTR(arg))
	{
		chprintln(ch, "Syntax: gredit create\n\r        gredit #/skill name");
		return;
	}

	if (is_number(arg))
		value = atoi(arg);
	else
		value = group_lookup(arg);

	if (value > -1)
	{
		pGroup = get_group_data(value);

		if (!pGroup || IS_NULLSTR(pGroup->name))
		{
			chprintln(ch, "That skill does not exist.");
			return;
		}

	}
	else if (!str_cmp(arg, "save"))
	{
		save_groups();
		chprintln(ch, "Group database saved.");
		return;
	}
	else if (!str_cmp(arg, "create"))
	{
		if (ch->pcdata->security < 9)
		{
			chprintln
				(ch, "grEdit : Insuffecient security to create new groups.");
			return;
		}

		gredit_create(ch, argument);

		return;
	}

	edit_start(ch, pGroup, ED_GROUP);
	return;
}

CH_CMD(do_raedit)
{
	RACE_DATA *pRace;
	int value;
	char arg[MSL];

	if (IS_NPC(ch))
		return;

	pRace = &race_table[0];

	argument = one_argument(argument, arg);

	if (IS_NULLSTR(arg))
	{
		chprintln(ch, "Syntax: raedit create\n\r        raedit #/race name");
		return;
	}

	if (is_number(arg))
		value = atoi(arg);
	else
		value = race_lookup(arg);

	if (value > 0)
	{
		pRace = get_race_data(value);

		if (!pRace || IS_NULLSTR(pRace->name))
		{
			chprintln(ch, "That race does not exist.");
			return;
		}

	}
	else if (!str_cmp(arg, "save"))
	{
		save_races();
		chprintln(ch, "Race database saved.");
		return;
	}
	else if (!str_cmp(arg, "create"))
	{
		if (ch->pcdata->security < 9)
		{
			chprintln
				(ch, "raEdit : Insuffecient security to create new races.");
			return;
		}

		raedit_create(ch, argument);

		return;
	}

	edit_start(ch, pRace, ED_RACE);
	return;
}

CH_CMD(do_cledit)
{
	CLASS_DATA *pClass;
	int value;
	char arg[MSL];

	if (IS_NPC(ch))
		return;

	pClass = &class_table[0];

	argument = one_argument(argument, arg);

	if (IS_NULLSTR(arg))
	{
		chprintln(ch, "Syntax: cledit create\n\r        cledit #/class name");
		return;
	}

	if (is_number(arg))
		value = atoi(arg);
	else
		value = class_lookup(arg);

	if (value > -1)
	{
		pClass = get_class_data(value);

		if (!pClass || IS_NULLSTR(pClass->name))
		{
			chprintln(ch, "That class does not exist.");
			return;
		}

	}
	else if (!str_cmp(arg, "save"))
	{
		save_classes();
		chprintln(ch, "Class database saved.");
		return;
	}
	else if (!str_cmp(arg, "create"))
	{
		if (ch->pcdata->security < 9)
		{
			chprintln
				(ch, "clEdit : Insuffecient security to create new class.");
			return;
		}

		cledit_create(ch, argument);

		return;
	}
	edit_start(ch, pClass, ED_CLASS);
	return;
}

void display_resets(CHAR_DATA * ch)
{
	ROOM_INDEX_DATA *pRoom;
	RESET_DATA *pReset;
	MOB_INDEX_DATA *pMob = NULL;
	char buf[MAX_STRING_LENGTH];
	char final[MAX_STRING_LENGTH];
	int iReset = 0;

	EDIT_ROOM(ch, pRoom);
	final[0] = '\0';

	chprintln(ch,
			  " No.  Loads    Description       Location         Vnum   Mx Mn Description"
			  "\n\r"
			  "==== ======== ============= =================== ======== ===== ===========");

	for (pReset = pRoom->reset_first; pReset; pReset = pReset->next)
	{
		OBJ_INDEX_DATA *pObj;
		MOB_INDEX_DATA *pMobIndex;
		OBJ_INDEX_DATA *pObjIndex;
		OBJ_INDEX_DATA *pObjToIndex;
		ROOM_INDEX_DATA *pRoomIndex;

		final[0] = '\0';
		sprintf(final, "[%2d] ", ++iReset);

		switch (pReset->command)
		{
		default:
			sprintf(buf, "Bad reset command: %c.", pReset->command);
			strcat(final, buf);
			break;

		case 'M':
			if (!(pMobIndex = get_mob_index(pReset->arg1)))
			{
				sprintf(buf, "Load Mobile - Bad Mob %ld\n\r", pReset->arg1);
				strcat(final, buf);
				continue;
			}

			if (!(pRoomIndex = get_room_index(pReset->arg3)))
			{
				sprintf(buf, "Load Mobile - Bad Room %ld\n\r", pReset->arg3);
				strcat(final, buf);
				continue;
			}

			pMob = pMobIndex;
			sprintf(buf,
					"M[%5ld] %-13.13s in room             R[%5ld] %2d-%2d %-15.15s\n\r",
					pReset->arg1, pMob->short_descr, pReset->arg3,
					pReset->arg2, pReset->arg4, pRoomIndex->name);
			strcat(final, buf);

			/*
			 * Check for pet shop.
			 * -------------------
			 */
			{
				ROOM_INDEX_DATA *pRoomIndexPrev;

				pRoomIndexPrev = get_room_index(pRoomIndex->vnum - 1);
				if (pRoomIndexPrev
					&& IS_SET(pRoomIndexPrev->room_flags, ROOM_PET_SHOP))
					final[5] = 'P';
			}

			break;

		case 'O':
			if (!(pObjIndex = get_obj_index(pReset->arg1)))
			{
				sprintf(buf, "Load Object - Bad Object %ld\n\r", pReset->arg1);
				strcat(final, buf);
				continue;
			}

			pObj = pObjIndex;

			if (!(pRoomIndex = get_room_index(pReset->arg3)))
			{
				sprintf(buf, "Load Object - Bad Room %ld\n\r", pReset->arg3);
				strcat(final, buf);
				continue;
			}

			sprintf(buf,
					"O[%5ld] %-13.13s in room             "
					"R[%5ld]       %-15.15s\n\r", pReset->arg1,
					pObj->short_descr, pReset->arg3, pRoomIndex->name);
			strcat(final, buf);

			break;

		case 'P':
			if (!(pObjIndex = get_obj_index(pReset->arg1)))
			{
				sprintf(buf, "Put Object - Bad Object %ld\n\r", pReset->arg1);
				strcat(final, buf);
				continue;
			}

			pObj = pObjIndex;

			if (!(pObjToIndex = get_obj_index(pReset->arg3)))
			{
				sprintf(buf,
						"Put Object - Bad To Object %ld\n\r", pReset->arg3);
				strcat(final, buf);
				continue;
			}

			sprintf(buf,
					"O[%5ld] %-13.13s inside              O[%5ld] %2d-%2d %-15.15s\n\r",
					pReset->arg1, pObj->short_descr, pReset->arg3,
					pReset->arg2, pReset->arg4, pObjToIndex->short_descr);
			strcat(final, buf);

			break;

		case 'G':
		case 'E':
			if (!(pObjIndex = get_obj_index(pReset->arg1)))
			{
				sprintf(buf,
						"Give/Equip Object - Bad Object %ld\n\r", pReset->arg1);
				strcat(final, buf);
				continue;
			}

			pObj = pObjIndex;

			if (!pMob)
			{
				sprintf(buf, "Give/Equip Object - No Previous Mobile\n\r");
				strcat(final, buf);
				break;
			}

			if (pMob->pShop)
			{
				sprintf(buf,
						"O[%5ld] %-13.13s in the inventory of S[%5ld]       %-15.15s\n\r",
						pReset->arg1, pObj->short_descr,
						pMob->vnum, pMob->short_descr);
			}
			else
				sprintf(buf,
						"O[%5ld] %-13.13s %-19.19s M[%5ld]       %-15.15s\n\r",
						pReset->arg1, pObj->short_descr,
						(pReset->command ==
						 'G') ? "in the inventory" :
						flag_string(wear_loc_strings, pReset->arg3),
						pMob->vnum, pMob->short_descr);
			strcat(final, buf);

			break;

			/*
			 * Doors are set in rs_flags don't need to be displayed.
			 * If you want to display them then uncomment the new_reset
			 * line in the case 'D' in load_resets in db.c and here.
			 */
		case 'D':
			pRoomIndex = get_room_index(pReset->arg1);
			sprintf(buf,
					"R[%5ld] %s door of %-19.19s reset to %s\n\r",
					pReset->arg1,
					capitalize(dir_name[pReset->arg2]),
					pRoomIndex->name, flag_string(door_resets, pReset->arg3));
			strcat(final, buf);

			break;
			/*
			 * End Doors Comment.
			 */
		case 'R':
			if (!(pRoomIndex = get_room_index(pReset->arg1)))
			{
				sprintf(buf,
						"Randomize Exits - Bad Room %ld\n\r", pReset->arg1);
				strcat(final, buf);
				continue;
			}

			sprintf(buf, "R[%5ld] Exits are randomized in %s\n\r",
					pReset->arg1, pRoomIndex->name);
			strcat(final, buf);

			break;
		}
		chprint(ch, final);
	}

	return;
}

/*****************************************************************************
 Name:		add_reset
 Purpose:	Inserts a new reset in the given index slot.
 Called by:	do_resets(olc.c).
 ****************************************************************************/
void add_reset(ROOM_INDEX_DATA * room, RESET_DATA * pReset, int pIndex)
{
	RESET_DATA *reset;
	int iReset = 0;

	pIndex--;

	if (pIndex == 0 || !room->reset_first)
	{
		LINK(pReset, room->reset_first, room->reset_last, next, prev);
		return;
	}

	for (reset = room->reset_first; reset; reset = reset->next)
	{
		if (++iReset == pIndex || reset->next == NULL)
			break;
	}

	INSERT(pReset, reset, room->reset_first, next, prev);
	return;
}

CH_CMD(do_resets)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char arg3[MAX_INPUT_LENGTH];
	char arg4[MAX_INPUT_LENGTH];
	char arg5[MAX_INPUT_LENGTH];
	char arg6[MAX_INPUT_LENGTH];
	char arg7[MAX_INPUT_LENGTH];
	RESET_DATA *pReset = NULL;

	argument = one_argument(argument, arg1);
	argument = one_argument(argument, arg2);
	argument = one_argument(argument, arg3);
	argument = one_argument(argument, arg4);
	argument = one_argument(argument, arg5);
	argument = one_argument(argument, arg6);
	argument = one_argument(argument, arg7);

	if (!IS_BUILDER(ch, ch->in_room->area))
	{
		chprintln(ch, "Resets: Invalid security for editing this area.");
		return;
	}

	/*
	 * Display resets in current room.
	 * -------------------------------
	 */
	if (arg1[0] == '\0')
	{
		if (ch->in_room->reset_first)
		{
			chprintln(ch, "Resets: M = mobile, R = room, O = object, "
					  "P = pet, S = shopkeeper");
			display_resets(ch);
		}
		else
			chprintln(ch, "No resets in this room.");
	}

	/*
	 * Take index number and search for commands.
	 * ------------------------------------------
	 */
	if (is_number(arg1))
	{
		ROOM_INDEX_DATA *pRoom = ch->in_room;

		/*
		 * Delete a reset.
		 * ---------------
		 */
		if (!str_cmp(arg2, "delete"))
		{
			int insert_loc = atoi(arg1);
			int iReset = -1;

			if (!ch->in_room->reset_first)
			{
				chprintln(ch, "No resets in this area.");
				return;
			}
			for (pReset = pRoom->reset_first; pReset; pReset = pReset->next)
			{
				if (++iReset == insert_loc - 1)
					break;
			}

			if (!pReset)
			{
				chprintln(ch, "Reset not found.");
				return;
			}
			UNLINK(pReset, pRoom->reset_first, pRoom->reset_last, next, prev);
			free_reset_data(pReset);
			chprintln(ch, "Reset deleted.");
			SET_BIT(ch->in_room->area->area_flags, AREA_CHANGED);
		}
		else
			/*
			 * Add a reset.
			 * ------------
			 */
			if ((!str_cmp(arg2, "mob") && is_number(arg3)) ||
				(!str_cmp(arg2, "obj") && is_number(arg3)))
		{
			/*
			 * Check for Mobile reset.
			 * -----------------------
			 */
			if (!str_cmp(arg2, "mob"))
			{
				if (get_mob_index(is_number(arg3) ? atol(arg3) : 1) == NULL)
				{
					chprintln(ch, "Mob no existe.");
					return;
				}
				pReset = new_reset_data();
				pReset->command = 'M';
				pReset->arg1 = atol(arg3);
				pReset->arg2 = is_number(arg4) ? atoi(arg4) : 1;	/* Max # */
				pReset->arg3 = ch->in_room->vnum;
				pReset->arg4 = is_number(arg5) ? atoi(arg5) : 1;	/* Min # */
			}
			else
				/*
				 * Check for Object reset.
				 * -----------------------
				 */
			if (!str_cmp(arg2, "obj"))
			{
				pReset = new_reset_data();
				pReset->arg1 = atol(arg3);
				/*
				 * Inside another object.
				 * ----------------------
				 */
				if (!str_prefix(arg4, "inside"))
				{
					OBJ_INDEX_DATA *temp;

					temp = get_obj_index(is_number(arg5) ? atol(arg5) : 1);
					if ((temp->item_type != ITEM_CONTAINER)
						&& (temp->item_type != ITEM_CORPSE_NPC))
					{
						chprintln(ch, "Objeto 2 no es container.");
						return;
					}
					pReset->command = 'P';
					pReset->arg2 = is_number(arg6) ? atoi(arg6) : 1;
					pReset->arg3 = is_number(arg5) ? atol(arg5) : 1;
					pReset->arg4 = is_number(arg7) ? atoi(arg7) : 1;
				}
				else
					/*
					 * Inside the room.
					 * ----------------
					 */
				if (!str_cmp(arg4, "room"))
				{
					if (get_obj_index(atol(arg3)) == NULL)
					{
						chprintln(ch, "Vnum no existe.");
						return;
					}
					pReset->command = 'O';
					pReset->arg2 = 0;
					pReset->arg3 = ch->in_room->vnum;
					pReset->arg4 = 0;
				}
				else
					/*
					 * Into a Mobile's inventory.
					 * --------------------------
					 */
				{
					if (flag_value(wear_loc_flags, arg4) == -1)
					{
						chprintln(ch, "Resets: '? wear-loc'");
						return;
					}
					if (get_obj_index(atol(arg3)) == NULL)
					{
						chprintln(ch, "Vnum no existe.");
						return;
					}
					pReset->arg1 = atol(arg3);
					pReset->arg3 = flag_value(wear_loc_flags, arg4);
					if (pReset->arg3 == WEAR_NONE)
						pReset->command = 'G';
					else
						pReset->command = 'E';
				}
			}
			add_reset(ch->in_room, pReset, atol(arg1));
			SET_BIT(ch->in_room->area->area_flags, AREA_CHANGED);
			chprintln(ch, "Reset added.");
		}
		else if (!str_cmp(arg2, "random") && is_number(arg3))
		{
			if (atoi(arg3) < 1 || atoi(arg3) > 6)
			{
				chprintln(ch, "Invalid argument.");
				return;
			}
			pReset = new_reset_data();
			pReset->command = 'R';
			pReset->arg1 = ch->in_room->vnum;
			pReset->arg2 = atoi(arg3);
			add_reset(ch->in_room, pReset, atol(arg1));
			SET_BIT(ch->in_room->area->area_flags, AREA_CHANGED);
			chprintln(ch, "Random exits reset added.");
		}
		else
		{
			chprintln(ch, "Syntax: RESET <number> OBJ <vnum> <wear_loc>");
			chprintln(ch,
					  "        RESET <number> OBJ <vnum> inside <vnum> [limit] [count]");
			chprintln(ch, "        RESET <number> OBJ <vnum> room");
			chprintln(ch,
					  "        RESET <number> MOB <vnum> [max #x area] [max #x room]");
			chprintln(ch, "        RESET <number> DELETE");
			chprintln(ch, "        RESET <number> RANDOM [#x exits]");
		}
	}

	return;
}

/*****************************************************************************
 Name:		do_alist
 Purpose:	Normal command to list areas and display area information.
 Called by:	interpreter(interp.c)
 ****************************************************************************/
CH_CMD(do_alist)
{
	char buf[MAX_STRING_LENGTH];
	char result[MAX_STRING_LENGTH * 2];	/* May need tweaking. */
	AREA_DATA *pArea;

	if (IS_NPC(ch))
		return;

	sprintf(result, "[%3s] [%-27s] (%-5s-%5s) [%-10s] %3s [%-10s]\n\r",
			"Num", "Area Name", "lvnum", "uvnum", "Filename", "Sec",
			"Builders");

	for (pArea = area_first; pArea; pArea = pArea->next)
	{
		sprintf(buf,
				"[%3d] %-29.29s (%-5ld-%5ld) %-12.12s [%d] [%-10.10s]\n\r",
				pArea->vnum, pArea->name, pArea->min_vnum,
				pArea->max_vnum, pArea->file_name, pArea->security,
				pArea->builders);
		strcat(result, buf);
	}

	chprint(ch, result);
	return;
}

int calc_avedam(int num_dice, int dam_dice)
{
	return ((1 + dam_dice) * num_dice / 2);
}

CH_CMD(do_avedam)
{
	int i, j;
	int k = 0;
	int lookingfor;

	if (IS_NULLSTR(argument))
	{
		chprintln(ch, "What average dam are you looking for?");
		return;
	}

	lookingfor = atoi(argument);
	chprintf(ch, "Possible dice combinations for ave dam: %d\n\r", lookingfor);
	chprintln(ch, "T_Dice D_Dice   T_Dice D_Dice");
	chprintln(ch, "------ ------   ------ ------");
	for (i = 1; i <= lookingfor; i++)
	{
		for (j = 1; j <= lookingfor; j++)
		{
			if (lookingfor == calc_avedam(i, j))
			{
				k++;
				chprintf(ch, "%6d %6d   ", i, j);
				if (k % 2 == 0)
					chprintln(ch, "");
			}
		}
	}
	chprintln(ch, "");
}

void *get_olc_show(int editor)
{
	switch (editor)
	{
	case ED_AREA:
		return (void *) aedit_show;
	case ED_ROOM:
		return (void *) redit_show;
	case ED_OBJECT:
		return (void *) oedit_show;
	case ED_MOBILE:
		return (void *) medit_show;
	case ED_MPCODE:
		return (void *) mpedit_show;
	case ED_HELP:
		return (void *) hedit_show;
	case ED_CLAN:
		return (void *) cedit_show;
	case ED_SOCIAL:
		return (void *) sedit_show;
	case ED_RACE:
		return (void *) raedit_show;
	case ED_SKILL:
		return (void *) skedit_show;
	case ED_GROUP:
		return (void *) gredit_show;
	case ED_CMD:
		return (void *) cmdedit_show;
	case ED_CLASS:
		return (void *) cledit_show;
	}
	return NULL;
}

void edit_start(CHAR_DATA * ch, void *OLC, int Ed)
{
	bool new_ed = FALSE;
	OLC_FUN *olc_fun;

	if (!ch || !ch->desc)
		return;

	if (ch->desc->editor != Ed)
		new_ed = TRUE;

	ch->desc->pEdit = (void *) OLC;
	ch->desc->editor = Ed;
	if ((olc_fun = (OLC_FUN *) get_olc_show(ch->desc->editor)) != NULL)
		(*olc_fun) (ch, "");
	if (new_ed)
	{
		act("$n has entered the $t editor.", ch, olc_ed_name_long(ch), NULL,
			TO_ROOM);
		act("You are now entering the $t editor, type 'done' to finish.", ch,
			olc_ed_name_long(ch), NULL, TO_CHAR);
	}
}