cotn/notes/
cotn/src/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments 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.                                               *
 *                                                                         *
 *  Dystopia Mud improvements copyright (C) 2000, 2001 by Brian Graversen  *
 *                                                                         *
 *  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.                                                  *
 ***************************************************************************/

/***************************************************************************
 *  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.                *
 *                                                                         *
 ***************************************************************************/
 /***************************************************************************
 *                                 _/                            _/        *
 *      _/_/_/  _/_/      _/_/_/  _/    _/_/    _/    _/    _/_/_/         *
 *     _/    _/    _/  _/        _/  _/    _/  _/    _/  _/    _/          *
 *    _/    _/    _/  _/        _/  _/    _/  _/    _/  _/    _/           *
 *   _/    _/    _/    _/_/_/  _/    _/_/      _/_/_/    _/_/_/            *
 ***************************************************************************
 * Mindcloud Copyright 2001-2003 by Jeff Boschee (Zarius),                 *
 * Additional credits are in the help file CODECREDITS                     *
 * All Rights Reserved.                                                    *
 ***************************************************************************/

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "olc.h"
#include "recycle.h"

/*
 * Local functions.
 */

/* Executed from comm.c.  Minimizes compiling when changes are made. */
bool run_olc_editor(DESCRIPTOR_DATA * d)
{
        switch (d->editor)
        {
        case ED_HELP:
                hedit(d->character, d->incomm);
                break;
        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;
        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_HELP:
                xprintf(buf, "HEdit");
                break;
        case ED_AREA:
                xprintf(buf, "AEdit");
                break;
        case ED_ROOM:
                xprintf(buf, "REdit");
                break;
        case ED_OBJECT:
                xprintf(buf, "OEdit");
                break;
        case ED_MOBILE:
                xprintf(buf, "MEdit");
                break;
        case ED_MPCODE:
                xprintf(buf, "MPEdit");
                break;
        case ED_OPCODE:
                xprintf(buf, "OPEdit");
                break;
        case ED_RPCODE:
                xprintf(buf, "RPEdit");
                break;
        default:
                xprintf(buf, " ");
                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;
        static char buf[10];

        buf[0] = '\0';
        switch (ch->desc->editor)
        {
        case ED_AREA:
                pArea = (AREA_DATA *) ch->desc->pEdit;
                xprintf(buf, "%d", pArea ? pArea->vnum : 0);
                break;
        case ED_ROOM:
                pRoom = ch->in_room;
                xprintf(buf, "%d", pRoom ? pRoom->vnum : 0);
                break;
        case ED_OBJECT:
                pObj = (OBJ_INDEX_DATA *) ch->desc->pEdit;
                xprintf(buf, "%d", pObj ? pObj->vnum : 0);
                break;
        case ED_MOBILE:
                pMob = (MOB_INDEX_DATA *) ch->desc->pEdit;
                xprintf(buf, "%d", pMob ? pMob->vnum : 0);
                break;
        case ED_MPCODE:
                pMprog = (PROG_CODE *) ch->desc->pEdit;
                xprintf(buf, "%d", pMprog ? pMprog->vnum : 0);
                break;
        case ED_OPCODE:
                pOprog = (PROG_CODE *) ch->desc->pEdit;
                xprintf(buf, "%d", pOprog ? pOprog->vnum : 0);
                break;
        case ED_RPCODE:
                pRprog = (PROG_CODE *) ch->desc->pEdit;
                xprintf(buf, "%d", pRprog ? pRprog->vnum : 0);
                break;
        default:
                xprintf(buf, " ");
                break;
        }

        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];
        int       cmd;
        int       col;

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

        if (col % 5 != 0)
                send_to_char("\n\r", ch);

        return;
}

/*****************************************************************************
 Name:		show_commands
 Purpose:	Display all olc commands.
 Called by:	olc interpreters.
 ****************************************************************************/
bool show_commands(CHAR_DATA * ch, char *argument)
{
        switch (ch->desc->editor)
        {
        case ED_HELP:
                show_olc_cmds(ch, hedit_table);
                break;
        case ED_AREA:
                show_olc_cmds(ch, aedit_table);
                break;
        case ED_ROOM:
                show_olc_cmds(ch, redit_table);
                break;
        case ED_OBJECT:
                show_olc_cmds(ch, oedit_table);
                break;
        case ED_MOBILE:
                show_olc_cmds(ch, medit_table);
                break;
        case ED_MPCODE:
                show_olc_cmds(ch, mpedit_table);
                break;
        case ED_OPCODE:
                show_olc_cmds(ch, opedit_table);
                break;
        case ED_RPCODE:
                show_olc_cmds(ch, rpedit_table);
                break;
        }

        return FALSE;
}

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

const struct olc_cmd_type hedit_table[] = {
        {"commands", show_commands},
        {"create", hedit_create},
        {"?", show_help},
        {"level", hedit_level},
        {"text", hedit_text},
        {"index", hedit_index},
        {"change", hedit_change},
        {"keyword", hedit_keyword},
        {"delete", hedit_delete},
        {"", 0,}
};

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

        {"age", aedit_age},
        {"builders", aedit_builder},
        {"commands", show_commands},
        {"create", aedit_create},
        {"filename", aedit_file},
        {"music", aedit_music},
        {"name", aedit_name},
        {"cvnum", aedit_cvnum},
        {"reset", aedit_reset},
        {"security", aedit_security},
        {"show", aedit_show},
        {"vnum", aedit_vnum},
        {"lvnum", aedit_lvnum},
        {"uvnum", aedit_uvnum},
        {"?", show_help},
        {"version", show_version},

        {"", 0,}
};

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

        {"commands", show_commands},
        {"create", redit_create},
        {"desc", redit_desc},
        {"ed", redit_ed},
        {"format", redit_format},
        {"name", redit_name},
        {"show", redit_show},

        {"north", redit_north},
        {"south", redit_south},
        {"east", redit_east},
        {"west", redit_west},
        {"up", redit_up},
        {"down", redit_down},
        {"walk", redit_move},
        {"rlist", redit_rlist},
        {"teleport", redit_teleport},
        {"portal", redit_portal},
        {"rprog", redit_rprog},
        {"texttrig", redit_texttrig},
        {"spell", redit_spell},
        {"action", redit_action},

        /*
         * New reset commands. 
         */
        {"mreset", redit_mreset},
        {"oreset", redit_oreset},
        {"mlist", redit_mlist},
        {"olist", redit_olist},
        {"mshow", redit_mshow},
        {"oshow", redit_oshow},

        {"?", show_help},
        {"version", show_version},
        {"addrprog", redit_addrprog},
        {"delrprog", redit_delrprog},
        {"shoptype", redit_shoptype},
        {"shopitem", redit_shopitem},

        {"", 0,}
};

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

        {"addaffect", oedit_addaffect},
        {"commands", show_commands},
        {"cost", oedit_cost},
        {"condition", oedit_condition},
        {"resistance", oedit_resistance},
        {"toughness", oedit_toughness},
        {"create", oedit_create},
        {"delaffect", oedit_delaffect},
        {"ed", oedit_ed},
        {"long", oedit_long},
        {"name", oedit_name},
        {"short", oedit_short},
        {"show", oedit_show},
        {"delete", oedit_delete},
        {"v0", oedit_value0},
        {"v1", oedit_value1},
        {"v2", oedit_value2},
        {"v3", oedit_value3},
        {"v4", oedit_value4},
        {"v5", oedit_value5},
        {"v6", oedit_value6},
        {"v7", oedit_value7},
        {"v8", oedit_value8},
        {"v9", oedit_value9},
        {"v10", oedit_value10},
        {"msg1", oedit_msg1},
        {"msg2", oedit_msg2},
        {"weight", oedit_weight},
        {"addoprog", oedit_addoprog},
        {"deloprog", oedit_deloprog},
        {"?", show_help},
        {"version", show_version},

        {"", 0,}
};

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

        {"alignment", medit_align},
        {"commands", show_commands},
        {"create", medit_create},
        {"desc", medit_desc},
        {"level", medit_level},
        //{   "bones",    medit_bones     },
        {"long", medit_long},
        {"name", medit_name},
        {"short", medit_short},
        {"show", medit_show},
        {"spec", medit_spec},
        {"quest", medit_quest},
        {"weapon", medit_weapon},
        {"addmprog", medit_addmprog},   /* ROM */
        {"delmprog", medit_delmprog},   /* ROM */
        {"position", medit_position},   /* ROM */
        {"v0", medit_value0},
        {"v1", medit_value1},
        {"v2", medit_value2},
        {"delete", medit_delete},
        {"shop", medit_shop},
        {"?", show_help},
        {"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->editor = 0;
        return FALSE;
}

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

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

        EDIT_AREA(ch, pArea);
        smash_tilde(argument);
        strcpy(arg, argument);
        argument = one_argument(argument, 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;
        }
*/
        /*
         * 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 ((value = flag_value(area_flags, arg)) != NO_FLAG)
        {
                TOGGLE_BIT(pArea->area_flags, value);

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

        if ((value = flag_value(area_bits, arg)) != NO_FLAG)
        {
                TOGGLE_BIT(pArea->areabits, value);

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

        if ((value = flag_value(asector_flags, arg)) != NO_FLAG)
        {
                pArea->sector = value;

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

        if ((value = flag_value(aweather_flags, arg)) != NO_FLAG)
        {
                TOGGLE_BIT(pArea->a_weather, value);

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

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

/* Room Interpreter, called by do_redit. */
void redit(CHAR_DATA * ch, char *argument)
{
        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;

        smash_tilde(argument);
        strcpy(arg, argument);
        argument = one_argument(argument, 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 (!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 ((value = flag_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 ((value = flag_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(CHAR_DATA * ch, char *argument)
{
        AREA_DATA *pArea;
        OBJ_INDEX_DATA *pObj;
        char      arg[MAX_STRING_LENGTH];
        char      command[MAX_INPUT_LENGTH];
        int       cmd;
        int       value;

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

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

/*    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 ( !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 ((value = flag_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 ((value = flag_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 ((value = flag_value(quest_flags, arg)) != NO_FLAG)
        {
                TOGGLE_BIT(pObj->quest, value);

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

        if ((value = flag_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 ((value = flag_value(furniture_flags, arg)) != NO_FLAG)
        {
                TOGGLE_BIT(pObj->value[2], value);

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

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

/* Mobile Interpreter, called by do_medit. */
void medit(CHAR_DATA * ch, char *argument)
{
        AREA_DATA *pArea;
        MOB_INDEX_DATA *pMob;
        char      command[MAX_INPUT_LENGTH];
        char      arg[MAX_STRING_LENGTH];
        int       cmd;
        int       value;

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

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

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

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

        if (!str_cmp(command, "done"))
        {
                edit_done(ch);
                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 ((value = flag_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 = flag_value(act_flags, arg)) != NO_FLAG)
        {
                TOGGLE_BIT(pMob->act, value);

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

        if ((value = flag_value(affect_flags, arg)) != NO_FLAG)
        {
                TOGGLE_BIT(pMob->affected_by, value);

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

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

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

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

        if (ch->trust < MAX_LEVEL - 5)
        {
                if (!IS_BUILDER(ch, pArea))
                {
                        send_to_char("Huh?\n\r", ch);
                        return;
                }
        }

        if (command[0] == 'r' && !str_prefix(command, "reset"))
        {
                if (ch->desc->editor == ED_AREA)
                        reset_area((AREA_DATA *) ch->desc->pEdit);
                else
                        reset_area(pArea);
                send_to_char("Area reset.\n\r", ch);
                return;
        }

        if (command[0] == 'c' && !str_prefix(command, "create"))
        {
                if (aedit_create(ch, argument))
                {
                        ch->desc->editor = ED_AREA;
                        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(atol(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->editor = ED_AREA;
        aedit_show(ch, "");
        return;
}

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

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

        if (ch->trust < MAX_LEVEL - 5)
        {
                if (!IS_BUILDER(ch, pRoom->area))
                {
                        send_to_char("Huh?\n\r", ch);
                        return;
                }
        }

        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->editor = ED_ROOM;
        redit_show(ch, "");
        return;
}

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

        argument = one_argument(argument, command);

        if (is_number(command))
        {
                pObj = get_obj_index(atol(command));
                if (!pObj)
                {
                        send_to_char("Invalid vnum\n\r", ch);
                        return;
                }

                if (ch->trust < MAX_LEVEL - 5)
                {
                        if (!IS_BUILDER(ch, pObj->area))
                        {
                                send_to_char("Huh?\n\r", ch);
                                return;
                        }
                }
        }

        if (!str_cmp(command, "delete"))
        {
                if (argument[0] == '\0')
                {
                        stc("Syntax: oedit delete [vnum]\n\r", ch);
                        return;
                }
                xprintf(buf, "$N deleting object '%s'.", argument);
                oedit_delete(ch, argument);
                return;
        }

        if (command[0] == 'c' && !str_prefix(command, "create"))
        {
                pArea = get_vnum_area(atol(argument));
                if (!pArea)
                {
                        send_to_char("No area with that vnum exists.\n\r",
                                     ch);
                        return;
                }
                if (!IS_BUILDER(ch, pArea))
                {
                        send_to_char("Huh?\n\r", ch);
                        return;
                }
        }

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

                ch->desc->pEdit = (void *) pObj;
                ch->desc->editor = ED_OBJECT;
                oedit_show(ch, "");
                return;
        }

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

        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, char *argument)
{
        MOB_INDEX_DATA *pMob = NULL;
        AREA_DATA *pArea = NULL;
        char      command[MAX_INPUT_LENGTH];
        char      buf[MSL];

        argument = one_argument(argument, command);

        if (is_number(command))
        {
                pMob = get_mob_index(atol(command));
                if (!pMob)
                {
                        send_to_char("Invalid vnum\n\r", ch);
                        return;
                }
                if (ch->trust < MAX_LEVEL - 5)
                {
                        if (!IS_BUILDER(ch, pMob->area))
                        {
                                send_to_char("Huh?\n\r", ch);
                                return;
                        }
                }
        }

        if (command[0] == 'c' && !str_prefix(command, "create"))
        {
                pArea = get_vnum_area(atol(argument));

                if (!pArea)
                {
                        send_to_char("Syntax : medit create <vnum>\n\r", ch);
                        return;
                }
                if (!IS_BUILDER(ch, pArea))
                {
                        send_to_char
                                ("You don't have enough security to edit this area.\n\r",
                                 ch);
                        return;
                }
        }

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

                ch->desc->pEdit = (void *) pMob;
                ch->desc->editor = ED_MOBILE;
                medit_show(ch, "");
                return;
        }

        if (!str_cmp(command, "delete"))
        {
                if (argument[0] == '\0')
                {
                        stc("Syntax: medit delete [vnum]\n\r", ch);
                        return;
                }
                xprintf(buf, "$N deleting mob '%s'.", argument);
                medit_delete(ch, argument);
                return;
        }

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

        send_to_char("MEdit:  There is no default mobile to edit.\n\r", ch);
        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';

        send_to_char
                (" No.  Loads    Description       Location         Vnum    Max  Description"
                 "\n\r"
                 "==== ======== ============= =================== ======== ===== ==========="
                 "\n\r", ch);

        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;

                buf[0] = '\0';
                xprintf(buf, "[%2d] ", ++iReset);
                send_to_char(buf, ch);

                switch (pReset->command)
                {
                default:
                        xprintf(buf, "Bad reset command: %c.",
                                pReset->command);
                        send_to_char(buf, ch);
                        break;

                case 'M':
                        if (!(pMobIndex = get_mob_index(pReset->arg1)))
                        {
                                xprintf(buf, "Load Mobile - Bad Mob %d\n\r",
                                        pReset->arg1);
                                send_to_char(buf, ch);
                                continue;
                        }

                        if (!(pRoomIndex = get_room_index(pReset->arg3)))
                        {
                                xprintf(buf, "Load Mobile - Bad Room %d\n\r",
                                        pReset->arg3);
                                send_to_char(buf, ch);
                                continue;
                        }

                        pMob = pMobIndex;
                        xprintf(buf,
                                "M[%5d] %-13.13s in room             R[%5d] [%3d] %-15.15s\n\r",
                                pReset->arg1, pMob->short_descr, pReset->arg3,
                                pReset->arg2, pRoomIndex->name);
                        send_to_char(buf, ch);

                        break;

                case 'O':
                        if (!(pObjIndex = get_obj_index(pReset->arg1)))
                        {
                                xprintf(buf,
                                        "Load Object - Bad Object %d\n\r",
                                        pReset->arg1);
                                send_to_char(buf, ch);
                                continue;
                        }

                        pObj = pObjIndex;

                        if (!(pRoomIndex = get_room_index(pReset->arg3)))
                        {
                                xprintf(buf, "Load Object - Bad Room %d\n\r",
                                        pReset->arg3);
                                send_to_char(buf, ch);
                                continue;
                        }

                        xprintf(buf, "O[%5d] %-13.13s in room             "
                                "R[%5d]       %-15.15s\n\r",
                                pReset->arg1, pObj->short_descr,
                                pReset->arg3, pRoomIndex->name);
                        send_to_char(buf, ch);

                        break;

                case 'P':
                        if (!(pObjIndex = get_obj_index(pReset->arg1)))
                        {
                                xprintf(buf, "Put Object - Bad Object %d\n\r",
                                        pReset->arg1);
                                send_to_char(buf, ch);
                                continue;
                        }

                        pObj = pObjIndex;

                        if (!(pObjToIndex = get_obj_index(pReset->arg3)))
                        {
                                xprintf(buf,
                                        "Put Object - Bad To Object %d\n\r",
                                        pReset->arg3);
                                send_to_char(buf, ch);
                                continue;
                        }

                        xprintf(buf,
                                "O[%5d] %-13.13s inside              O[%5d]       %-15.15s\n\r",
                                pReset->arg1,
                                pObj->short_descr,
                                pReset->arg3, pObjToIndex->short_descr);
                        send_to_char(buf, ch);
                        break;

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

                        pObj = pObjIndex;

                        if (!pMob)
                        {
                                xprintf(buf,
                                        "Give/Equip Object - No Previous Mobile\n\r");
                                send_to_char(buf, ch);
                                break;
                        }


                        xprintf(buf,
                                "O[%5d] %-13.13s %-19.19s M[%5d]       %-15.15s\n\r",
                                pReset->arg1,
                                pObj->short_descr,
                                (pReset->command == 'G') ?
                                flag_string(wear_loc_strings, WEAR_NONE)
                                : flag_string(wear_loc_strings, pReset->arg3),
                                pMob->vnum, pMob->short_descr);

                        send_to_char(buf, ch);

                        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 );
                         xprintf( buf, "R[%5d] %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 ) );
                         send_to_char(buf,ch);
                         
                         break;
                         *
                         * End Doors Comment.
                         */
                case 'R':
                        if (!(pRoomIndex = get_room_index(pReset->arg1)))
                        {
                                xprintf(buf,
                                        "Randomize Exits - Bad Room %d\n\r",
                                        pReset->arg1);
                                send_to_char(buf, ch);
                                continue;
                        }

                        xprintf(buf, "R[%5d] Exits are randomized in %s\n\r",
                                pReset->arg1, pRoomIndex->name);
                        send_to_char(buf, ch);

                        break;
                }
        }

        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 id)
{
        RESET_DATA *reset;
        int       iReset = 0;

        if (!room->reset_first)
        {
                room->reset_first = pReset;
                room->reset_last = pReset;
                pReset->next = NULL;
                return;
        }

        id--;

        if (id == 0)    /* First slot (1) selected. */
        {
                pReset->next = room->reset_first;
                room->reset_first = pReset;
                return;
        }

        /*
         * If negative slot( <= 0 selected) then this will find the last.
         */
        for (reset = room->reset_first; reset->next; reset = reset->next)
        {
                if (++iReset == id)
                        break;
        }

        pReset->next = reset->next;
        reset->next = pReset;
        if (!pReset->next)
                room->reset_last = pReset;
        return;
}

void do_resets(CHAR_DATA * ch, char *argument)
{
        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];
        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);

        /*
         * Display resets in current room.
         * -------------------------------
         */
        if (!IS_BUILDER(ch, ch->in_room->area))
        {
                send_to_char("Huh?\n\r", ch);
                return;
        }

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

        /*
         * 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 = atol(arg1);

                        if (!ch->in_room->reset_first)
                        {
                                send_to_char("No resets in this area.\n\r",
                                             ch);
                                return;
                        }

                        if (insert_loc - 1 <= 0)
                        {
                                pReset = pRoom->reset_first;
                                pRoom->reset_first = pRoom->reset_first->next;
                                if (!pRoom->reset_first)
                                        pRoom->reset_last = NULL;
                        }
                        else
                        {
                                int       iReset = 0;
                                RESET_DATA *prev = NULL;

                                for (pReset = pRoom->reset_first;
                                     pReset; pReset = pReset->next)
                                {
                                        if (++iReset == insert_loc)
                                                break;
                                        prev = pReset;
                                }

                                if (!pReset)
                                {
                                        send_to_char("Reset not found.\n\r",
                                                     ch);
                                        return;
                                }

                                if (prev)
                                        prev->next = prev->next->next;
                                else
                                        pRoom->reset_first =
                                                pRoom->reset_first->next;

                                for (pRoom->reset_last = pRoom->reset_first;
                                     pRoom->reset_last->next;
                                     pRoom->reset_last =
                                     pRoom->reset_last->next);
                        }

                        free_reset_data(pReset);
                        send_to_char("Reset deleted.\n\r", ch);
                        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"))
                        {
                                pReset = new_reset_data();
                                pReset->command = 'M';
                                pReset->arg1 = atol(arg3);
                                pReset->arg2 = is_number(arg4) ? atol(arg4) : 1;    /* Max # */
                                pReset->arg3 = ch->in_room->vnum;
                        }
                        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"))
                                {
                                        pReset->command = 'P';
                                        pReset->arg2 = 0;
                                        pReset->arg3 =
                                                is_number(arg5) ? atol(arg5) :
                                                1;
                                }
                                else
                                        /*
                                         * Inside the room.
                                         * ----------------
                                         */
                                if (!str_cmp(arg4, "room"))
                                {
                                        pReset = new_reset_data();
                                        pReset->command = 'O';
                                        pReset->arg1 = atol(arg3);
                                        pReset->arg2 = 0;
                                        pReset->arg3 = ch->in_room->vnum;
                                }
                                else
                                        /*
                                         * Into a Mobile's inventory.
                                         * --------------------------
                                         */
                                {
                                        if (flag_value(wear_loc_flags, arg4)
                                            == NO_FLAG)
                                        {
                                                send_to_char
                                                        ("Resets: '? wear-loc'\n\r",
                                                         ch);
                                                return;
                                        }
                                        if (get_obj_index(atol(arg3)) == NULL)
                                        {
                                                send_to_char
                                                        ("That vnum does not exist.\n\r",
                                                         ch);
                                                return;
                                        }

                                        pReset = new_reset_data();
                                        pReset->arg1 = atol(arg3);
                                        pReset->arg3 =
                                                flag_value(wear_loc_flags,
                                                           arg4);
                                        if (pReset->arg2 == WEAR_NONE)
                                                pReset->command = 'G';
                                        else
                                                pReset->command = 'E';
                                }
                        }

                        add_reset(ch->in_room, pReset, atol(arg1));
                        send_to_char("Reset added.\n\r", ch);
                        SET_BIT(ch->in_room->area->area_flags, AREA_CHANGED);
                }
                else
                {
                        send_to_char
                                ("Syntax: RESET <number> OBJ <vnum> <wear_loc>\n\r",
                                 ch);
                        send_to_char
                                ("        RESET <number> OBJ <vnum> in <vnum>\n\r",
                                 ch);
                        send_to_char
                                ("        RESET <number> OBJ <vnum> room\n\r",
                                 ch);
                        send_to_char
                                ("        RESET <number> MOB <vnum> [<max #>]\n\r",
                                 ch);
                        send_to_char("        RESET <number> DELETE\n\r", ch);
                }
        }

        return;
}

/*****************************************************************************
 Name:		do_alist
 Purpose:	Normal command to list areas and display area information.
 Called by:	interpreter(interp.c)
 ****************************************************************************/
void do_alist(CHAR_DATA * ch, char *argument)
{
        char      buf[MAX_STRING_LENGTH];
        AREA_DATA *pArea;
        BUFFER   *buffer;

        if (IS_NPC(ch))
                return;

        buffer = new_buf();

        if (ch->pcdata->security < 2)
        {
                send_to_char("Huh?\n\r", ch);
                return;
        }
        xprintf(buf, "[%3s] [%-27s] (%-5s-%5s) [%-10s] %3s [%-10s]\n\r",
                "Num", "Area Name", "lvnum", "uvnum", "Filename", "Sec",
                "Builders");
        //send_to_char(buf,ch);
        add_buf(buffer, buf);
        for (pArea = area_first; pArea; pArea = pArea->next)
        {
                xprintf(buf,
                        "[%3d] %-29.29s (%-5d-%5d) %-12.12s [%d] [%-10.10s]\n\r",
                        pArea->vnum, pArea->name, pArea->lvnum, pArea->uvnum,
                        pArea->filename, pArea->security, pArea->builders);
                //send_to_char(buf, ch);
                add_buf(buffer, buf);
        }
        pager_to_char(buf_string(buffer), ch);
        free_buf(buffer);
        return;
}

void hedit(CHAR_DATA * ch, char *argument)
{
        HELP_DATA *pHelp;
        char      command[MAX_INPUT_LENGTH];
        char      arg[MAX_INPUT_LENGTH];
        int       cmd;

        if (str_cmp(argument, "change"))
                EDIT_HELP(ch, pHelp);

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

        if (command[0] == '\0')
                return;

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

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

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

void do_hedit(CHAR_DATA * ch, char *argument)
{
/* 	HELP_DATA *pHelp; */
        char      arg1[MAX_INPUT_LENGTH + 20];

        argument = one_argument(argument, arg1);
        if (ch->level < (MAX_LEVEL - 10))
        {
                send_to_char("huh?\n\r", ch);
                return;
        }
        if (!str_cmp(arg1, "create"))
        {
                hedit_create(ch, argument);
                ch->desc->editor = ED_HELP;
                return;
        }
        else if (!str_cmp(arg1, "change"))
        {
                hedit_change(ch, argument);
                ch->desc->editor = ED_HELP;
                return;
        }
        else if (!str_cmp(arg1, "index"))
        {
                hedit_index(ch, argument);
                ch->desc->editor = ED_HELP;
                return;
        }
        else if (!str_cmp(arg1, "delete"))
        {
                hedit_delete(ch, argument);
                ch->desc->editor = ED_HELP;
                return;
        }
        else
        {
                send_to_char
                        ("Hedit mode entered, no default command or help to edit.\n\r",
                         ch);
                ch->desc->editor = ED_HELP;
                return;
        }
}