daleken/
daleken/data/notes/
daleken/data/player/
daleken/data/system/poses/
daleken/doc/Homepage/images/
daleken/log/
/*___________________________________________________________________________*
   )()(			  DalekenMUD 1.12 (C) 2000			)()(
   `]['		       by Martin Thomson, Lee Brooks,			`]['
    ||		       Ken Herbert and David Jacques			 ||
    || ----------------------------------------------------------------- ||
    || Envy Diku Mud improvements copyright (C) 1994 by Michael Quan,	 ||
    || David Love, Guilherme 'Willie' Arnold, and Mitchell Tse.		 ||
    || Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael	 ||
    || Chastain, Michael Quan, and Mitchell Tse.			 ||
    || Original Diku Mud copyright (C) 1990, 1991			 ||
    || by Sebastian Hammer, Michael Seifert, Hans Henrik St{rfeldt,	 ||
    || Tom Madsen, and Katja Nyboe.					 ||
    || ----------------------------------------------------------------- ||
    || Any use of this software must follow the licenses of the		 ||
    || creators.  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.					 ||
    || ----------------------------------------------------------------- ||
    ||                               olc.c                               ||
    || Central interpreters for OLC and all miscellaneous OLC code.      ||
 *_/<>\_________________________________________________________________/<>\_*/


#include "mud.h"
#include "olc.h"
#include "db.h"

/*
 * Local functions.
 */
AREA_DATA *get_area_data args( ( int vnum ) );


AREA_DATA *get_editing_area( CHAR_DATA *ch )
{
    if( !ch->desc )
	return ch->in_room->area;

    /* Find the area to save. */
    if( !str_cmp( ch->desc->interpreter->name, "AEdit" ) )
	return (AREA_DATA *) ch->desc->pEdit;
    if( !str_cmp( ch->desc->interpreter->name, "OEdit" ) )
	return ( (OBJ_INDEX_DATA *) ch->desc->pEdit )->area;
    if( !str_cmp( ch->desc->interpreter->name, "MEdit" ) )
	return ( (MOB_INDEX_DATA *) ch->desc->pEdit )->area;
    if( !str_cmp( ch->desc->interpreter->name, "HEdit" ) )
	return ( (HELP_DATA *) ch->desc->pEdit )->area;

    return ch->in_room->area;
}


bool is_builder( CHAR_DATA *ch, AREA_DATA *area )
{
    CHAR_DATA *rch;
    const char *p;
    char arg[ MAX_INPUT_LENGTH ];

    if( !area || !ch->desc || !( rch = get_char( ch ) ) )
	return FALSE;

    if( rch->pcdata->security >= area->security )
	return TRUE;

    p = area->builders;
    while( p[0] != '\0' )
    {
	p = one_argument( p, arg );
	if( !str_cmp( arg, rch->name ) || !str_cmp( arg, "all" ) )
	    return TRUE;
    }

    return FALSE;
}


const char *olc_ed_vnum( CHAR_DATA *ch )
{
    AREA_DATA *pArea;
    ROOM_INDEX_DATA *pRoom;
    OBJ_INDEX_DATA *pObj;
    MOB_INDEX_DATA *pMob;
    SOCIAL_DATA *pSocial;
    HELP_DATA *pHelp;
    RELIGION_DATA *pReligion;
    CLAN_DATA *pClan;
    PLANE_DATA *pPlane;
    MPROG_GLOBAL *mprg;
    static char buf[10];

    buf[0] = '\0';
    if( !ch->desc )
	return " ";


    if( !str_cmp( ch->desc->interpreter->name, "AEdit" ) )
    {
	pArea = (AREA_DATA *) ch->desc->pEdit;
	sprintf( buf, "%d", pArea ? pArea->vnum : 0 );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "REdit" ) )
    {
	pRoom = ch->in_room;
	sprintf( buf, "%d", pRoom ? pRoom->vnum : 0 );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "OEdit" ) )
    {
	pObj = (OBJ_INDEX_DATA *) ch->desc->pEdit;
	sprintf( buf, "%d", pObj ? pObj->vnum : 0 );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "MEdit" ) )
    {
	pMob = (MOB_INDEX_DATA *) ch->desc->pEdit;
	sprintf( buf, "%d", pMob ? pMob->vnum : 0 );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "SEdit" ) )
    {
	if( ( pSocial = (SOCIAL_DATA *) ch->desc->pEdit ) )
	    return pSocial->name;
	return "<none>";
    }
    else if( !str_cmp( ch->desc->interpreter->name, "HEdit" ) )
    {
	if( ( pHelp = (HELP_DATA *) ch->desc->pEdit ) )
	    return pHelp->keyword;
	return "<none>";
    }
    else if( !str_cmp( ch->desc->interpreter->name, "RelEdit" ) )
    {
	if( ( pReligion = (RELIGION_DATA *) ch->desc->pEdit ) )
	    return pReligion->name;
	return "<none>";
    }
    else if( !str_cmp( ch->desc->interpreter->name, "CEdit" ) )
    {
	if( ( pClan = (CLAN_DATA *) ch->desc->pEdit ) )
	    return  pClan->name;
	return "<none>";
    }
    else if( !str_cmp( ch->desc->interpreter->name, "PoseEdit" ) )
	strcpy( buf, "--" );
    else if( !str_cmp( ch->desc->interpreter->name, "PlEdit" ) )
    {
	if( ( pPlane = (PLANE_DATA *)ch->desc->pEdit ) )
	    return pPlane->name;
	strcpy( buf, "--" );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "GMPEdit" ) )
    {
	mprg = (MPROG_GLOBAL *)ch->desc->pEdit;
	sprintf( buf, "%d", mprg ? mprg->vnum : 0 );
    }
    else
	strcpy( buf, " " );

    return buf;
}


const char *olc_ed_string( CHAR_DATA *ch )
{
    AREA_DATA *pArea;
    ROOM_INDEX_DATA *pRoom;
    OBJ_INDEX_DATA *pObj;
    MOB_INDEX_DATA *pMob;
    SOCIAL_DATA *pSocial;
    HELP_DATA *pHelp;
    RELIGION_DATA *pReligion;
    CLAN_DATA *pClan;
    PLANE_DATA *pPlane;
    MPROG_GLOBAL *mprg;
    static char buf[128];

    buf[0] = '\0';
    if( !ch->desc )
	return " ";

    if( !str_cmp( ch->desc->interpreter->name, "AEdit" ) )
    {
	if( ( pArea = (AREA_DATA *) ch->desc->pEdit ) )
	    sprintf( buf, "%s", pArea->name );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "REdit" ) )
    {
	if( ( pRoom = ch->in_room ) )
	    first_arg( pRoom->name, buf, FALSE );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "OEdit" ) )
    {
	if( ( pObj = (OBJ_INDEX_DATA *) ch->desc->pEdit ) )
	    first_arg( pObj->name, buf, FALSE );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "MEdit" ) )
    {
	if( ( pMob = (MOB_INDEX_DATA *) ch->desc->pEdit ) )
	    first_arg( pMob->name, buf, FALSE );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "SEdit" ) )
    {
	if( ( pSocial = (SOCIAL_DATA *) ch->desc->pEdit ) )
	    return pSocial->name;
    }
    else if( !str_cmp( ch->desc->interpreter->name, "HEdit" ) )
    {
	if( ( pHelp = (HELP_DATA *) ch->desc->pEdit ) )
	    first_arg( pHelp->keyword, buf, FALSE );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "RelEdit" ) )
    {
	if( ( pReligion = (RELIGION_DATA *) ch->desc->pEdit ) )
	    return pReligion->name;
    }
    else if( !str_cmp( ch->desc->interpreter->name, "CEdit" ) )
    {
	if( ( pClan = (CLAN_DATA *) ch->desc->pEdit ) )
	    return pClan->name;
    }
    else if( !str_cmp( ch->desc->interpreter->name, "PoseEdit" ) )
    {
	return "<some pose>";
    }
    else if( !str_cmp( ch->desc->interpreter->name, "PlEdit" ) )
    {
	if( ( pPlane = (PLANE_DATA *) ch->desc->pEdit ) )
	    return pPlane->name;
    }
    else if( !str_cmp( ch->desc->interpreter->name, "GMPEdit" ) )
    {
	if( ( mprg = (MPROG_GLOBAL *)ch->desc->pEdit ) )
	    return flag_string( mud_prog_flags, &mprg->type );
	return "--";
    }
    else
	strcpy( buf, " " );

    return buf;
}



/*****************************************************************************
 Name:		show_olc_cmds
 Purpose:	Format up the commands from given table.
 Called by:	show_commands( olc_act.c ).
 ****************************************************************************/
void show_olc_cmds( CHAR_DATA *ch, const struct olc_cmd_type *olc_table )
{
    char buf[MAX_STRING_LENGTH];
    char buf1[MAX_STRING_LENGTH];
    int cmd;
    int col;

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

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

    send_to_char( buf1, ch );
    return;
}


/*****************************************************************************
 Name:		show_commands
 Purpose:	Display all olc commands.
 Called by:	olc interpreters.
 ****************************************************************************/
bool show_commands( CHAR_DATA *ch, const char *argument )
{
    if( !str_cmp( ch->desc->interpreter->name, "AEdit" ) )
	show_olc_cmds( ch, aedit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "REdit" ) )
	show_olc_cmds( ch, redit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "OEdit" ) )
	show_olc_cmds( ch, oedit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "MEdit" ) )
	show_olc_cmds( ch, medit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "SEdit" ) )
	show_olc_cmds( ch, sedit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "HEdit" ) )
	show_olc_cmds( ch, hedit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "RelEdit" ) )
	show_olc_cmds( ch, reledit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "CEdit" ) )
	show_olc_cmds( ch, cedit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "PoseEdit" ) )
	show_olc_cmds( ch, poseedit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "PlEdit" ) )
	show_olc_cmds( ch, pledit_table );
    else if( !str_cmp( ch->desc->interpreter->name, "GMPEdit" ) )
	show_olc_cmds( ch, gmpedit_table );

    return FALSE;
}


/*****************************************************************************
 *			     Interpreter Tables.			     *
 *****************************************************************************/
const struct olc_cmd_type aedit_table[] =
{
/*  {	command		function	}, */

    { "age",		aedit_age	},
    { "builders",	aedit_builder	},
    { "clear",		aedit_clear	},
    { "count",		aedit_count	},
    { "create",		aedit_create	},
    { "describe",	aedit_desc	},
    { "economy",	aedit_economy	},
    { "filename",	aedit_file	},
    { "gmplist",	edit_gmplist	},
    { "name",		aedit_name	},
    { "order",		aedit_order	},
    { "plane",		aedit_plane	},
    { "recall",		aedit_recall	},
    { "repop",		aedit_repop	},
    { "reset",		aedit_reset	},
    { "security",	aedit_security	},
    { "show",		aedit_show	},
    { "temp",		aedit_temp	},
    { "vnum",		aedit_vnum	},
    { "lvnum",		aedit_lvnum	},
    { "uvnum",		aedit_uvnum	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type redit_table[] =
{
/*  {	command		function	}, */

    { "create",		redit_create	},
    { "clone",		redit_clone	},
    { "desc",		redit_desc	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "down",		redit_down	},
    { "east",		redit_east	},
    { "ed",		redit_ed	},
    { "format",		redit_format	},
    { "gmplist",	edit_gmplist	},
    { "oreset",		redit_oreset	},
    { "mlist",		redit_mlist	},
    { "mpshow",		redit_mpshow	},
    { "mpadd",		redit_mpadd	},
    { "mpdelete",	redit_mpdelete	},
    { "mpedit",		redit_mpedit	},
    { "mreset",		redit_mreset	},
    { "mshow",		redit_mshow	},
    { "name",		redit_name	},
    { "north",		redit_north	},
    { "olist",		redit_olist	},
    { "show",		redit_show	},
    { "oshow",		redit_oshow	},
    { "south",		redit_south	},
    { "up",		redit_up	},
    { "walk",		redit_move	},
    { "west",		redit_west	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type oedit_table[] =
{
/*  {	command		function	}, */

    { "action",		oedit_action	},
    { "addaffect",	oedit_addaffect	},
    { "addperm",	oedit_addperm	},
    { "addspell",	oedit_addspell	},
    { "clone",		oedit_clone	},
    { "condition",	oedit_condition	},
    { "cost",		oedit_cost	},
    { "create",		oedit_create	},
    { "delaffect",	oedit_delaffect	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "ed",		oedit_ed	},
    { "gmplist",	edit_gmplist	},
    { "level",		oedit_level	},
    { "long",		oedit_long	},
    { "mpshow",		oedit_mpshow	},
    { "mpadd",		oedit_mpadd	},
    { "mpdelete",	oedit_mpdelete	},
    { "mpedit",		oedit_mpedit	},
    { "name",		oedit_name	},
    { "repop",		oedit_repop	},
    { "required",	oedit_required	},
    { "rsfind",		oedit_rsfind	},
    { "short",		oedit_short	},
    { "show",		oedit_show	},
    { "v0",		oedit_value0	},
    { "v1",		oedit_value1	},
    { "v2",		oedit_value2	},
    { "v3",		oedit_value3	},
    { "weight",		oedit_weight	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type medit_table[] =
{
/*  {	command		function	}, */

    { "alignment",	medit_align	},
    { "class",		medit_class	},
    { "clone",		medit_clone	},
    { "create",		medit_create	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "desc",		medit_desc	},
    { "level",		medit_level	},
    { "long",		medit_long	},
    { "gmplist",	edit_gmplist	},
    { "mpshow",		medit_mpshow	},
    { "mpadd",		medit_mpadd	},
    { "mpdelete",	medit_mpdelete	},
    { "mpedit",		medit_mpedit	},
    { "name",		medit_name	},
    { "repop",		medit_repop	},
    { "rsfind",		medit_rsfind	},
    { "shop",		medit_shop	},
    { "short",		medit_short	},
    { "show",		medit_show	},
    { "spec",		medit_spec	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type sedit_table[] =
{
/*  {	command		function	}, */

    { "create",		sedit_create	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "name",		sedit_name	},
    { "show",		sedit_show	},

    { "char_no_arg",	sedit_cna	},
    { "cna",		sedit_cna	},
    { "others_no_arg",	sedit_ona	},
    { "ona",		sedit_ona	},
    { "char_found",	sedit_cf	},
    { "cf",		sedit_cf	},
    { "others_found",	sedit_of	},
    { "of",		sedit_of	},
    { "victim_found",	sedit_vf	},
    { "vf",		sedit_vf	},
    { "char_auto",	sedit_ca	},
    { "ca",		sedit_ca	},
    { "others_auto",	sedit_oa	},
    { "oa",		sedit_oa	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type hedit_table[] =
{
/*  {	command		function	}, */

    { "create",		hedit_create	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "show",		hedit_show	},

    { "harea",		hedit_harea	},
    { "hlist",		hedit_hlist	},
    { "keywords",	hedit_keyword	},
    { "level",		hedit_trust	},
    { "name",		hedit_keyword	},
    { "text",		hedit_text	},
    { "trust",		hedit_trust	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type reledit_table[] =
{
/*  {	command		function		}, */

    { "addskill",	reledit_addskill	},
    { "alignment",	reledit_align		},
    { "create",		reledit_create		},
    { "delet",		edit_delet		},
    { "delete",		edit_delete		},
    { "delskill",	reledit_delskill	},
    { "display",	reledit_display		},
    { "godname",	reledit_god		},
    { "name",		reledit_name		},
    { "show",		reledit_show		},
    { "token",		reledit_token		},

    { "?",		show_help		},
    { "commands",	show_commands		},
    { "version",	show_version		},

    { "", 0 }
};


const struct olc_cmd_type cedit_table[] =
{
/*  {	command		function		}, */

    { "addskill",	cedit_addskill	},
    { "class",		cedit_class	},
    { "create",		cedit_create	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "delskill",	cedit_delskill	},
    { "description",	cedit_desc	},
    { "display",	cedit_display	},
    { "enemies",	cedit_enemies	},
    { "motto",		cedit_motto	},
    { "name",		cedit_name	},
    { "leader",		cedit_leader	},
    { "recall",		cedit_recall	},
    { "religion",	cedit_religion	},
    { "rules",		cedit_rules	},
    { "show",		cedit_show	},
    { "story",		cedit_desc	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type poseedit_table[] =
{
/*  {	command		function		}, */

    { "char",		poseedit_tochar	},
    { "create",		poseedit_create	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "room",		poseedit_toroom	},
    { "show",		poseedit_show	},
    { "tochar",		poseedit_tochar	},
    { "toroom",		poseedit_toroom	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type pledit_table[] =
{
/*  {	command		function		}, */

    { "create",		pledit_create	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "minimum",	pledit_minimum	},
    { "name",		pledit_name	},
    { "show",		pledit_show	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


const struct olc_cmd_type gmpedit_table[] =
{
/*  {	command		function		}, */

    { "area",		gmpedit_area	},
    { "arglist",	gmpedit_arglist	},
    { "arguments",	gmpedit_arglist	},
    { "comlist",	gmpedit_comlist	},
    { "create",		gmpedit_create	},
    { "delet",		edit_delet	},
    { "delete",		edit_delete	},
    { "script",		gmpedit_comlist	},
    { "show",		gmpedit_show	},

    { "?",		show_help	},
    { "commands",	show_commands	},
    { "version",	show_version	},

    { "", 0 }
};


/*****************************************************************************
 *			    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 )
{
    ch->desc->pEdit = NULL;
    ch->desc->interpreter = get_interpreter( "" );
    return FALSE;
}


/*
 * Generic edit function for deleting things.
 */
bool edit_delet( CHAR_DATA *ch, const char *argument )
{
    send_to_char( "Are you really sure you want to do this?\n\r", ch );
    return FALSE;
}


void unlink_reset( ROOM_INDEX_DATA *pRoom, RESET_DATA *pReset )
{
    RESET_DATA *prev = NULL;

    if( pReset == pRoom->reset_first )
	pRoom->reset_first = pRoom->reset_first->next;
    else
    {
	for( prev = pRoom->reset_first; prev; prev = prev->next )
	    if( prev->next == pReset )
		break;

	if( prev )
	    prev->next = pReset->next;
    }

    if( pReset == pRoom->reset_last )
	pRoom->reset_last = prev;
}


void delete_room_index( ROOM_INDEX_DATA *pRoom )
{
    CHAR_DATA *mch, *mch_next;
    OBJ_DATA *obj, *obj_next;
    int i;

    /* clean of objects and characters */
    for( mch = pRoom->people; mch; mch = mch_next )
    {
	mch_next = mch->next;
	char_from_room( mch );
	if( IS_NPC( mch ) )
	    extract_char( mch, TRUE );
	else
	    char_to_room( mch, get_room_index( ROOM_VNUM_IMMPLANE ) );
    }
    for( obj = pRoom->contents; obj; obj = obj_next )
    {
	obj_next = obj->next;
	extract_obj( obj );
    }
    if( pRoom->vnum == top_vnum_room )
	for( i = pRoom->vnum; i > 0; --i )
	    if( get_room_index( i ) )
	    {
		top_vnum_room = i;
		break;
	    }
    free_room_index( pRoom );
}


void delete_mob_index( MOB_INDEX_DATA *pMob )
{
    ROOM_INDEX_DATA *pRoom;
    RESET_DATA *rst, *rst_next;
    CHAR_DATA *mch, *mch_next;
    int i;
    bool foundmob = FALSE;
    bool foundobj = FALSE;

    for( i = 0; i < MAX_KEY_HASH; i++ )
    {
	for( pRoom = room_index_hash[i]; pRoom; pRoom = pRoom->next )
	{
	    for( mch = pRoom->people; pMob->count > 0 && mch;
		 mch = mch_next )
	    {
		mch_next = mch->next;
		if( mch->deleted || mch->pIndexData == pMob )
		    continue;
		extract_char( mch, TRUE );
	    }

	    /* Remove resets.
	     * Known Bug: This may remove 'P' resets falsely, or not
	     * properly.
	     */
	    for( rst = pRoom->reset_first; rst; rst = rst_next )
	    {
		rst_next = rst->next;
		switch( rst->command )
		{
		case 'M':
		    if( rst->arg1 == pMob->vnum )
		    {
			unlink_reset( pRoom, rst );
			free_reset_data( rst );

			SET_BIT( pRoom->area->area_flags,  AREA_CHANGED );
			foundmob = TRUE;
		    }
		    else
			foundmob = FALSE;
		    break;

		case 'E':
		case 'G':
		    if( foundmob )
		    {
			foundobj = TRUE;

			unlink_reset( pRoom, rst );
			free_reset_data( rst );

			SET_BIT( pRoom->area->area_flags, AREA_CHANGED );
		    }
		    else
			foundobj = FALSE;
		    break;

		case 'P':
		    if( foundobj && foundmob )
		    {
			unlink_reset( pRoom, rst );
			free_reset_data( rst );

			SET_BIT( pRoom->area->area_flags, AREA_CHANGED );
		    }
		}
	    }
	}
    }

    if( pMob->vnum == top_vnum_mob )
	for( i = pMob->vnum; i > 0; --i )
	    if( get_mob_index( i ) )
	    {
		top_vnum_mob = i;
		break;
	    }
    top_mob_index--;

    free_mob_index( pMob );
}


void delete_obj_index( OBJ_INDEX_DATA *pObj )
{
    ROOM_INDEX_DATA *pRoom;
    RESET_DATA *rst, *rst_next;
    OBJ_DATA *obj, *obj_next;
    int i;

    for( obj = object_list; obj; obj = obj_next )
    {
	obj_next = obj->next;
	if( obj->deleted || obj->pIndexData != pObj )
	    continue;
	extract_obj( obj );
    }

    /* Remove all of the resets for this object.
     * Known Bug: If obj1 resets inside this object and obj2 resets
     *            inside obj1, then the reset for obj2 is not removed.
     *            A stack system could probably fix this problem but it
     *            really isn't worth the effort.
     */
    for( i = 0; i < MAX_KEY_HASH; i++ )
    {
	for( pRoom = room_index_hash[i]; pRoom; pRoom = pRoom->next )
	{
	    for( rst = pRoom->reset_first; rst; rst = rst_next )
	    {
		rst_next = rst->next;
		switch( rst->command )
		{
		case 'O':	case 'E':
		case 'P':	case 'G':
		    if( ( rst->arg1 == pObj->vnum )
			|| ( rst->command == 'P'
			     && rst->arg2 == pObj->vnum ) )
		    {
			unlink_reset( pRoom, rst );
			free_reset_data( rst );

			SET_BIT( pRoom->area->area_flags, AREA_CHANGED );
		    }
		}
	    }
	}
    }

    if( pObj->vnum == top_vnum_obj )
	for( i = pObj->vnum; i > 0; --i )
	    if( get_obj_index( i ) )
	    {
		top_vnum_obj = i;
		break;
	    }
    top_obj_index--;

    free_obj_index( pObj );
}


/*
 * Generic edit function for deleting things.
 */
bool edit_delete( CHAR_DATA *ch, const char *argument )
{
    HELP_DATA *pHelp;
    SOCIAL_DATA *pSocial;
    ROOM_INDEX_DATA *pRoom;
    MOB_INDEX_DATA *pMob;
    OBJ_INDEX_DATA *pObj;
    MPROG_GLOBAL *mprg;

    if( str_cmp( argument, "confirm" ) )
    {
	send_to_char( "Please type 'delete confirm' to delete this.\n\r", ch  );
	return FALSE;
    }

    if( !str_cmp( ch->desc->interpreter->name, "REdit" ) )
    {
	EDIT_ROOM( ch, pRoom );
	char_from_room( ch );
	char_to_room( ch, get_room_index( ROOM_VNUM_IMMPLANE ) );
	delete_room_index( pRoom );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "OEdit" ) )
    {
	EDIT_OBJ( ch, pObj );
	delete_obj_index( pObj );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "MEdit" ) )
    {
	EDIT_MOB( ch, pMob );
	delete_mob_index( pMob );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "SEdit" ) )
    {
	EDIT_SOCIAL( ch, pSocial );
	free_social( pSocial );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "HEdit" ) )
    {
	EDIT_HELP( ch, pHelp );
	free_help( pHelp );
    }
    else if( !str_cmp( ch->desc->interpreter->name, "GMPEdit" ) )
    {
	EDIT_GMPROG( ch, mprg );
	send_to_char(
	    "Warning, this can cause some programs not to work.\n\r", ch );
	free_mprog_global( mprg );
    }
    else
    {
	send_to_char( "You can't delete that.\n\r", ch );
	return FALSE;
    }

    edit_done( ch );
    send_to_char( "Ok.\n\r", ch );
    return TRUE;
}


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


/* Area Interpreter, called by do_aedit. */
void aedit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    AREA_DATA *pArea;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_INPUT_LENGTH];
    int cmd;
    int value;

    EDIT_AREA( ch, pArea );

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( !IS_BUILDER( ch, pArea ) )
	send_to_char( "AEdit:  Insufficient security to modify area.\n\r", ch );

    if( command[0] == '\0' )
    {
	aedit_show( ch, argument );
	return;
    }

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

    if( !IS_BUILDER( ch, pArea ) )
    {
	interpret( ch, arg );
	return;
    }

    if( command[1] == '\0' && ( command[0] == '+' || command[0] == '-' ) )
    {
	value = pArea->vnum;
	if( command[0] == '+' )
	    value++;
	else
	    value--;
	if( !( pArea = get_area_data( value ) ) )
	{
	    send_to_char( "There is no area there.\n\r", ch );
	    return;
	}
	ch->desc->pEdit = (void *)pArea;
	aedit_show( ch, "" );
	return;
    }

    /* Search Table and Dispatch Command. */
    for( cmd = 0; *aedit_table[cmd].name; cmd++ )
    {
	if( !str_prefix( command, aedit_table[cmd].name ) )
	{
	    if( ( *aedit_table[cmd].olc_fun ) ( ch, argument ) )
		SET_BIT( pArea->area_flags, AREA_CHANGED );
	    return;
	}
    }

    /* Take care of flags. */
    if( flag_value( &value, area_flags, arg ) != NO_FLAG )
    {
	TOGGLE_BIT( pArea->area_flags, value );
	SET_BIT( pArea->area_flags, AREA_CHANGED );

	send_to_char( "Flag toggled.\n\r", ch );
	return;
    }

    /* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Room Interpreter, called by do_redit. */
void redit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    ROOM_INDEX_DATA *pRoom;
    AREA_DATA *pArea;
    char arg[MAX_STRING_LENGTH];
    char command[MAX_INPUT_LENGTH];
    int cmd;
    int value;

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

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( !IS_BUILDER( ch, pArea ) )
	send_to_char( "REdit:  Insufficient security to modify room.\n\r", ch );

    if( command[0] == '\0' )
    {
	redit_show( ch, argument );
	return;
    }

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

    if( ( command[0] == '+' || command[0] == '-' )
	&& ( command[1] == '\0' || is_number( command ) ) )
    {
	value = pRoom->vnum;
	if( command[1] == '\0' )
	{
	    command[1] = '1';
	    command[2] = '\0';
	}
	value += atoi( command );

	if( !( pRoom = get_room_index( value ) ) )
	{
	    send_to_char( "There is no room there.\n\r", ch );
	    return;
	}
	char_from_room( ch );
	char_to_room( ch, pRoom );
	ch->desc->pEdit = (void *)pRoom;
	redit_show( ch, "" );
	return;
    }

    if( !IS_BUILDER( ch, pArea ) )
    {
	interpret( ch, arg );
	return;
    }

    /* Search Table and Dispatch Command. */
    for( cmd = 0; *redit_table[cmd].name; cmd++ )
    {
	if( !str_prefix( command, redit_table[cmd].name ) )
	{
	    if( ( *redit_table[cmd].olc_fun ) ( ch, argument ) )
		SET_BIT( pArea->area_flags, AREA_CHANGED );
	    return;
	}
    }

    /* Take care of flags. */
    if( flag_value( &value, room_flags, arg ) != NO_FLAG )
    {
	TOGGLE_BIT( pRoom->room_flags, value );

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Room flag toggled.\n\r", ch );
	return;
    }

    if( flag_value( &value, sector_flags, arg ) != NO_FLAG )
    {
	pRoom->sector_type = value;

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Sector type set.\n\r", ch );
	return;
    }

    /* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Object Interpreter, called by do_oedit. */
void oedit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    AREA_DATA *pArea;
    OBJ_INDEX_DATA *pObj;
    char arg[MAX_STRING_LENGTH];
    char command[MAX_INPUT_LENGTH];
    int cmd;
    int value;

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

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( !IS_BUILDER( ch, pArea ) )
	send_to_char( "OEdit: Insufficient security to modify area.\n\r", ch );

    if( command[0] == '\0' )
    {
	oedit_show( ch, argument );
	return;
    }

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

    if( ( command[0] == '+' || command[0] == '-' )
	&& ( command[1] == '\0' || is_number( command ) ) )
    {
	value = pObj->vnum;
	if( command[1] == '\0' )
	{
	    command[1] = '1';
	    command[2] = '\0';
	}
	value += atoi( command );
	if( !( pObj = get_obj_index( value ) ) )
	{
	    send_to_char( "There is no object there.\n\r", ch );
	    return;
	}
	ch->desc->pEdit = (void *)pObj;
	oedit_show( ch, "" );
	return;
    }

    if( !IS_BUILDER( ch, pArea ) )
    {
	interpret( ch, arg );
	return;
    }

    /* Search Table and Dispatch Command. */
    for( cmd = 0; *oedit_table[cmd].name; cmd++ )
    {
	if( !str_prefix( command, oedit_table[cmd].name ) )
	{
	    if( ( *oedit_table[cmd].olc_fun ) ( ch, argument ) )
		SET_BIT( pArea->area_flags, AREA_CHANGED );
	    return;
	}
    }

    /* Take care of flags. */
    if( flag_value( &value, type_flags, arg ) != NO_FLAG )
    {
	pObj->item_type = value;

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Type set.\n\r", ch );

	/*
	 * Clear the values.
	 */
	pObj->value[0] = 0;
	pObj->value[1] = 0;
	pObj->value[2] = 0;
	pObj->value[3] = 0;

	return;
    }

    if( flag_value( &value, extra_flags, arg ) != NO_FLAG )
    {
	TOGGLE_BIT( pObj->extra_flags, value );

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Extra flag toggled.\n\r", ch );
	return;
    }

    if( flag_value( &value, wear_flags, arg ) != NO_FLAG )
    {
	TOGGLE_BIT( pObj->wear_flags, value );

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Wear flag toggled.\n\r", ch );
	return;
    }

    if( flag_value( &value, material_flags, arg ) != NO_FLAG )
    {
	pObj->material = value;

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Item material type set.\n\r", ch );
	return;
    }

    /* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Mobile Interpreter, called by do_medit. */
void medit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    AREA_DATA *pArea;
    MOB_INDEX_DATA *pMob;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_STRING_LENGTH];
    int cmd;
    int value;
    int vect[MAX_VECTOR];

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

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( !IS_BUILDER( ch, pArea ) )
	send_to_char( "MEdit: Insufficient security to modify area.\n\r", ch );

    if( command[0] == '\0' )
    {
	medit_show( ch, argument );
	return;
    }

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

    if( ( command[0] == '+' || command[0] == '-' )
	&& ( command[1] == '\0' || is_number( command ) ) )
    {
	value = pMob->vnum;
	if( command[1] == '\0' )
	{
	    command[1] = '1';
	    command[2] = '\0';
	}
	value += atoi( command );
	if( !( pMob = get_mob_index( value ) ) )
	{
	    send_to_char( "There is no mobile there.\n\r", ch );
	    return;
	}
	ch->desc->pEdit = (void *)pMob;
	medit_show( ch, "" );
	return;
    }

    if( !IS_BUILDER( ch, pArea ) )
    {
	interpret( ch, arg );
	return;
    }

    /* Search Table and Dispatch Command. */
    for( cmd = 0; *medit_table[cmd].name; cmd++ )
    {
	if( !str_prefix( command, medit_table[cmd].name ) )
	{
	    if( ( *medit_table[cmd].olc_fun ) ( ch, argument ) )
		SET_BIT( pArea->area_flags, AREA_CHANGED );
	    return;
	}
    }

    /* Take care of flags. */
    if( flag_value( &value, sex_flags, arg ) != NO_FLAG )
    {
	pMob->sex = value;

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Sex set.\n\r", ch );
	return;
    }

    if( ( value = race_full_lookup( arg ) ) != NO_FLAG )
    {
	pMob->race = value;
	pMob->body_parts = race_table[pMob->race].body_parts;

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Race set.\n\r", ch );
	return;
    }

    if( flag_value( vect, act_flags, arg ) != NO_FLAG )
    {
	for( value = 0; value < MAX_VECTOR; value++ )
	    pMob->act[value] ^= vect[value];

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Act flag toggled.\n\r", ch );
	return;
    }

    if( flag_value( vect, affect_flags, arg ) != NO_FLAG )
    {
	for( value = 0; value < MAX_VECTOR; value++ )
	    pMob->affected_by[value] ^= vect[value];

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Affect flag toggled.\n\r", ch );
	return;
    }

    if( flag_value( &value, body_part_flags, arg ) != NO_FLAG )
    {
	TOGGLE_BIT( pMob->body_parts, value );

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Body part flag toggled.\n\r", ch );
	return;
    }

    /* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Social Interpreter, called by do_sedit. */
void sedit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_STRING_LENGTH];
    int cmd;

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( command[0] == '\0' )
    {
	sedit_show( ch, argument );
	return;
    }

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

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

    /* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Help Interpreter, called by do_hedit. */
void hedit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    AREA_DATA *pArea;
    HELP_DATA *pHelp;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_STRING_LENGTH];
    int cmd;

    EDIT_HELP( ch, pHelp );
    pArea = pHelp->area;

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( !IS_BUILDER( ch, pArea ) )
	send_to_char( "HEdit: Insufficient security to modify area.\n\r", ch );

    if( command[0] == '\0' )
    {
	hedit_show( ch, argument );
	return;
    }

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

    if( !IS_BUILDER( ch, pArea ) )
    {
	interpret( ch, arg );
	return;
    }

    /* Search Table and Dispatch Command. */
    for( cmd = 0; *hedit_table[cmd].name; cmd++ )
    {
	if( !str_prefix( command, hedit_table[cmd].name ) )
	{
	    if( ( *hedit_table[cmd].olc_fun ) ( ch, argument ) )
		SET_BIT( pArea->area_flags, AREA_CHANGED );
	    return;
	}
    }

    /* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Religion Interpreter, called by do_reledit. */
void reledit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    RELIGION_DATA *pReligion;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_STRING_LENGTH];
    int cmd, value;

    EDIT_RELIGION( ch, pReligion );

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( command[0] == '\0' )
    {
	reledit_show( ch, argument );
	return;
    }

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

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

    if( flag_value( &value, sac_event_flags, arg ) != NO_FLAG )
    {
	TOGGLE_BIT( pReligion->sac_events, value );

	send_to_char( "Sacrificial Event toggled.\n\r", ch );
	return;
    }

/* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Clan Interpreter, called by do_cedit. */
void cedit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    CLAN_DATA *pClan;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_STRING_LENGTH];
    int cmd, value;

    EDIT_CLAN( ch, pClan );

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( command[0] == '\0' )
    {
	cedit_show( ch, argument );
	return;
    }

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

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

    if( flag_value( &value, clan_type_flags, arg ) != NO_FLAG )
    {
	pClan->clan_type = value;

	charprintf( ch, "Clan type changed to %s.\n\r", arg );
	return;
    }

/* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Pose Interpreter, called by do_cedit. */
void poseedit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_STRING_LENGTH];
    int cmd;

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( command[0] == '\0' )
    {
	poseedit_show( ch, argument );
	return;
    }

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

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

/* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Plane Interpreter, called by do_pledit. */
void pledit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_STRING_LENGTH];
    int cmd;

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( command[0] == '\0' )
    {
	pledit_show( ch, argument );
	return;
    }

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

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

/* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


/* Global Mud Program Interpreter, called by do_gmpedit. */
void gmpedit( DESCRIPTOR_DATA *d, const char *argument )
{
    CHAR_DATA *ch = d->character;
    MPROG_GLOBAL *mprg;
    AREA_DATA *pArea;
    char command[MAX_INPUT_LENGTH];
    char arg[MAX_STRING_LENGTH];
    int cmd, value;

    EDIT_GMPROG( ch, mprg );
    pArea = mprg->area;

    strcpy( arg, argument );
    argument = one_argument( arg, command );

    if( command[0] == '\0' )
    {
	gmpedit_show( ch, argument );
	return;
    }

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

    if( ( command[0] == '+' || command[0] == '-' )
	&& ( command[1] == '\0' || is_number( command ) ) )
    {
	value = mprg->vnum;
	if( command[1] == '\0' )
	{
	    command[1] = '1';
	    command[2] = '\0';
	}
	value += atoi( command );
	if( !( mprg = get_global_mudprog_index( value ) ) )
	{
	    send_to_char( "There is no mudprog there.\n\r", ch );
	    return;
	}
	ch->desc->pEdit = (void *)mprg;
	gmpedit_show( ch, "" );
	return;
    }

    if( !IS_BUILDER( ch, pArea ) )
    {
	interpret( ch, arg );
	return;
    }

    /* Search Table and Dispatch Command. */
    for( cmd = 0; *gmpedit_table[cmd].name; cmd++ )
    {
	if( !str_prefix( command, gmpedit_table[cmd].name ) )
	{
	    if( (*gmpedit_table[cmd].olc_fun) ( ch, argument ) )
		SET_BIT( pArea->area_flags, AREA_CHANGED );
	    return;
	}
    }

    if( ( value = flag_value( NULL, mud_prog_flags, arg ) ) != NO_FLAG )
    {
	mprg->type = value;

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Type set.\n\r", ch );
	return;
    }

    if( ( value = flag_value( NULL, mor_type_flags, arg ) ) != NO_FLAG )
    {
	TOGGLE_BIT( mprg->allowed, value );

	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Allowed types set.\n\r", ch );
	return;
    }

    /* Default to Standard Interpreter. */
    interpret( ch, arg );
    return;
}


void do_aedit( CHAR_DATA *ch, const char *argument )
{
    AREA_DATA *pArea;
    char command[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "aedit" ) )
	return;

    argument = one_argument( argument, command );
    pArea = ch->in_room->area;

    if( command[0] == 'r' && !str_prefix( command, "reset" ) )
    {
	int save_player;

	if( !str_cmp( ch->desc->interpreter->name, "AEdit" ) )
	    pArea = (AREA_DATA *) ch->desc->pEdit;

	save_player = pArea->nplayer;
	pArea->nplayer = 0;
	reset_area( pArea );
	pArea->nplayer = save_player;
	send_to_char( "Area reset.\n\r", ch );
	return;
    }

    if( command[0] == 'c' && !str_prefix( command, "create" ) )
    {
	if( aedit_create( ch, argument ) )
	{
	    ch->desc->interpreter = get_interpreter( "AEdit" );
	    pArea = (AREA_DATA *) ch->desc->pEdit;
	    SET_BIT( pArea->area_flags, AREA_CHANGED );
	    aedit_show( ch, "" );
	}
	return;
    }

    if( is_number( command ) )
    {
	if( !( pArea = get_area_data( atoi( command ) ) ) )
	{
	    send_to_char( "No such area vnum exists.\n\r", ch );
	    return;
	}
    }

    /*
     * Builder defaults to editing current area.
     */
    ch->desc->pEdit = (void *)pArea;
    ch->desc->interpreter = get_interpreter( "AEdit" );
    aedit_show( ch, "" );
    return;
}


/* Entry point for editing room_index_data. */
void do_redit( CHAR_DATA *ch, const char *argument )
{
    ROOM_INDEX_DATA *pRoom;
    char command[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "redit" ) )
	return;

    argument = one_argument( argument, command );
    pRoom = ch->in_room;

    if( command[0] == 'r' && !str_prefix( command, "reset" ) )
    {
	reset_room( pRoom );
	send_to_char( "Room reset.\n\r", ch );
	return;
    }

    if( command[0] == 'c' && !str_prefix( command, "create" ) )
    {
	if( redit_create( ch, argument ) )
	{
	    char_from_room( ch );
	    char_to_room( ch, ch->desc->pEdit );
	    SET_BIT( pRoom->area->area_flags, AREA_CHANGED );
	}
    }

    /*
     * Builder defaults to editing current room.
     */
    ch->desc->pEdit = ch->in_room;
    ch->desc->interpreter = get_interpreter( "REdit" );
    redit_show( ch, "" );
    return;
}


/* Entry point for editing obj_index_data. */
void do_oedit( CHAR_DATA *ch, const char *argument )
{
    OBJ_INDEX_DATA *pObj;
    AREA_DATA *pArea;
    char command[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "oedit" ) )
	return;

    argument = one_argument( argument, command );

    if( is_number( command ) )
    {
	if( !( pObj = get_obj_index( atoi( command ) ) ) )
	{
	    send_to_char( "OEdit:  That vnum does not exist.\n\r", ch );
	    return;
	}

	ch->desc->pEdit = (void *)pObj;
	ch->desc->interpreter = get_interpreter( "OEdit" );
	oedit_show( ch, "" );
	return;
    }

    if( command[0] == 'c' && !str_prefix( command, "create" ) )
    {
	if( oedit_create( ch, argument ) )
	{
	    pArea = get_vnum_area( atoi( argument ) );
	    SET_BIT( pArea->area_flags, AREA_CHANGED );
	    ch->desc->interpreter = get_interpreter( "OEdit" );
	    oedit_show( ch, "" );
	}
	return;
    }

    if( get_obj_index( 1 ) )
	do_oedit( ch, "1" );
    else
	send_to_char( "OEdit:  There is no default object to edit.\n\r", ch );
    return;
}


/* Entry point for editing mob_index_data. */
void do_medit( CHAR_DATA *ch, const char *argument )
{
    MOB_INDEX_DATA *pMob;
    AREA_DATA *pArea;
    char command[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "medit" ) )
	return;

    argument = one_argument( argument, command );

    if( is_number( command ) )
    {
	if( !( pMob = get_mob_index( atoi( command ) ) ) )
	{
	    send_to_char( "MEdit:  That vnum does not exist.\n\r", ch );
	    return;
	}

	ch->desc->pEdit = (void *)pMob;
	ch->desc->interpreter = get_interpreter( "MEdit" );
	medit_show( ch, "" );
	return;
    }

    if( command[0] == 'c' && !str_prefix( command, "create" ) )
    {
	if( medit_create( ch, argument ) )
	{
	    pArea = get_vnum_area( atoi( argument ) );
	    SET_BIT( pArea->area_flags, AREA_CHANGED );
	    ch->desc->interpreter = get_interpreter( "MEdit" );
	    medit_show( ch, "" );
	}
	return;
    }

    if( get_mob_index( 1 ) )
	do_medit( ch, "1" );
    else
	send_to_char( "MEdit:  There is no default mobile to edit.\n\r", ch );
    return;
}


void do_sedit( CHAR_DATA *ch, const char *argument )
{
    SOCIAL_DATA *pSocial;
    AREA_DATA *pArea;
    char buf[MAX_INPUT_LENGTH];

    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "sedit" ) )
	return;

    argument = one_argument( argument, buf );
    pArea = ch->in_room->area;
    if( !IS_BUILDER( ch, pArea ) )
    {
	send_to_char( "You can't edit socials here.\n\r", ch );
	return;
    }
    if( !str_cmp( buf, "create" ) )
    {
	if( sedit_create( ch, argument ) )
	{
	    SET_BIT( pArea->area_flags, AREA_CHANGED );
	    ch->desc->interpreter = get_interpreter( "SEdit" );
	    sedit_show( ch, "" );
	}
	return;
    }

    if( !( pSocial = find_social( buf ) ) )
    {
	charprintf( ch, "SEdit:  Can't find the %s social.\n\r", buf );
	return;
    }

    ch->desc->pEdit = (void *)pSocial;
    ch->desc->interpreter = get_interpreter( "SEdit" );
    sedit_show( ch, "" );
    return;
}


void do_hedit( CHAR_DATA *ch, const char *argument )
{
    HELP_DATA *pHelp;
    AREA_DATA *pArea;
    char buf[MAX_INPUT_LENGTH];
    char arg[MAX_INPUT_LENGTH];
    int num, count = 0;
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "hedit" ) )
	return;

    strcpy( buf, argument );
    argument = one_argument( argument, arg );
    pArea = ch->in_room->area;
    if( !IS_BUILDER( ch, pArea ) )
    {
	send_to_char( "You can't edit helps here.\n\r", ch );
	return;
    }
    if( !str_cmp( arg, "create" ) )
    {
	if( hedit_create( ch, argument ) )
	{
	    SET_BIT( pArea->area_flags, AREA_CHANGED );
	    ch->desc->interpreter = get_interpreter( "HEdit" );
	}
	return;
    }

    num = number_argument( buf, buf );
    for( pHelp = help_first; pHelp; pHelp = pHelp->next )
    {
	if( abs( pHelp->level ) > get_trust( ch ) )
	    continue;

	if( help_keyword( buf, pHelp->keyword ) && ++count == num )
	    break;
    }
    if( !pHelp )
    {
	send_to_char( "HEdit: There is no help to edit.\n\r", ch );
	return;
    }
    if( !IS_BUILDER( ch, pHelp->area ) )
    {
	send_to_char( "That help is in an area you can't edit.\n\r", ch );
	sprintf( buf, "You need to be able to edit the area: [%4d] %s\n\r",
		!pHelp->area ? -1 : pHelp->area->vnum,
		!pHelp->area ? "No Area" : pHelp->area->name );
	send_to_char( buf, ch );
	return;
    }

    ch->desc->pEdit = (void *)pHelp;
    ch->desc->interpreter = get_interpreter( "HEdit" );
    hedit_show( ch, "" );
    return;
}


void do_reledit( CHAR_DATA *ch, const char *argument )
{
    RELIGION_DATA *pReligion;
    char buf[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "reledit" ) )
	return;

    argument = one_argument( argument, buf );
    if( !str_cmp( buf, "create" ) )
    {
	if( reledit_create( ch, argument ) )
	    ch->desc->interpreter = get_interpreter( "RelEdit" );
	return;
    }

    if( !( pReligion = religion_lookup( buf ) ) )
    {
	send_to_char( "RelEdit: There is no religion to edit.\n\r", ch );
	return;
    }

    ch->desc->pEdit = (void *)pReligion;
    ch->desc->interpreter = get_interpreter( "RelEdit" );
    reledit_show( ch, "" );
    return;
}


void do_cedit( CHAR_DATA *ch, const char *argument )
{
    CLAN_DATA *pClan;
    char buf[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "cedit" ) )
	return;

    argument = one_argument( argument, buf );
    if( !str_cmp( buf, "create" ) )
    {
	if( cedit_create( ch, argument ) )
	    ch->desc->interpreter = get_interpreter( "CEdit" );
	return;
    }

    if( !( pClan = clan_lookup( buf ) ) )
    {
	send_to_char( "CEdit: There is no clan to edit.\n\r", ch );
	return;
    }

    ch->desc->pEdit = (void *)pClan;
    ch->desc->interpreter = get_interpreter( "CEdit" );
    cedit_show( ch, "" );
    return;
}


void do_pledit( CHAR_DATA *ch, const char *argument )
{
    PLANE_DATA *pPlane;
    char buf[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "pledit" ) )
	return;

    argument = one_argument( argument, buf );
    if( !str_cmp( buf, "create" ) )
    {
	if( pledit_create( ch, argument ) )
	    ch->desc->interpreter = get_interpreter( "PlEdit" );
	return;
    }

    if( !( pPlane = plane_lookup( buf ) ) )
    {
	send_to_char( "PlEdit: There is no plane to edit.\n\r", ch );
	return;
    }

    ch->desc->pEdit = (void *)pPlane;
    ch->desc->interpreter = get_interpreter( "PlEdit" );
    pledit_show( ch, "" );
    return;
}


void do_gmpedit( CHAR_DATA *ch, const char *argument )
{
    MPROG_GLOBAL *mprg;
    char buf[MAX_INPUT_LENGTH];
    CHAR_DATA *rch;

    rch = get_char( ch );

    if( !authorized( rch, "gmpedit" ) )
	return;

    argument = one_argument( argument, buf );
    if( !str_cmp( buf, "create" ) )
    {
	if( gmpedit_create( ch, argument ) )
	    ch->desc->interpreter = get_interpreter( "GMPEdit" );
	return;
    }

    if( !( mprg = get_global_mudprog_index( atoi( buf ) ) ) )
    {
	send_to_char( "GMPEdit: There is no mudprog to edit.\n\r", ch );
	return;
    }

    ch->desc->pEdit = (void *)mprg;
    ch->desc->interpreter = get_interpreter( "GMPEdit" );
    gmpedit_show( ch, "" );
    return;
}