Rot/deity/
Rot/player/
Rot/src/utils/pfiles/
Rot/src/utils/www/
/***************************************************************************
 *  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.                                               *
 *                                                                         *
 *  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.                                                  *
 ***************************************************************************/

/***************************************************************************
*	ROM 2.4 is copyright 1993-1995 Russ Taylor			   *
*	ROM has been brought to you by the ROM consortium		   *
*	    Russ Taylor (rtaylor@pacinfo.com)				   *
*	    Gabrielle Taylor (gtaylor@pacinfo.com)			   *
*	    Brian Moore (rom@rom.efn.org)				   *
*	By using this code, you have agreed to follow the terms of the	   *
*	ROM license, in the file Rom24/doc/rom.license			   *
***************************************************************************/

/*************************************************************************** 
*       ROT 1.4 is copyright 1996-1997 by Russ Walsh                       * 
*       By using this code, you have agreed to follow the terms of the     * 
*       ROT license, in the file doc/rot.license                           * 
***************************************************************************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <malloc.h>
#include "merc.h"
#include "lookup.h"
#include "tables.h"
 
#if !defined(macintosh)
extern  int     _filbuf         args( (FILE *) );
#endif


void	save_area	args( ( FILE *fp ) );
void	save_helps	args( ( FILE *fp ) );
void 	save_mobiles	args( ( FILE *fp ) );
void 	save_objects	args( ( FILE *fp ) );
void	save_resets	args( ( FILE *fp ) );
void	save_rooms	args( ( FILE *fp ) );
void	save_shops	args( ( FILE *fp ) );
void 	save_socials	args( ( FILE *fp ) );
void	save_specials	args( ( FILE *fp ) );
void	save_dreams	args( ( FILE *fp ) );

int			newvnum;
int			newmin;
int			newmax;
bool			changevnum;

extern	int		first_room;
extern	int		first_object;
extern	int		first_mobile;
extern	int		last_room;
extern	int		last_object;
extern	int		last_mobile;

extern	MOB_INDEX_DATA *	mob_index;
extern	OBJ_INDEX_DATA *	obj_index;
extern	ROOM_INDEX_DATA *	room_index;
extern	DRM_INDEX_DATA *	drm_index;


/*
 * Converts an integer into letter-based flags.
 */
char *print_flags(int flag)
{
    int count, pos = 0;
    static char buf[52];


    for (count = 0; count < 32;  count++)
    {
        if (IS_SET(flag,1<<count))
        {
            if (count < 26)
                buf[pos] = 'A' + count;
            else
                buf[pos] = 'a' + (count - 26);
            pos++;
        }
    }

    if (pos == 0)
    {
        buf[pos] = '0';
        pos++;
    }

    buf[pos] = '\0';

    return buf;
}

/*
 * Compares flag aint to flag bint and returns flags
 * in bint, but not in aint.
 */
char *cmp_flags(int aint, int bint)
{
    int count, pos = 0;
    static char buf[52];


    for (count = 0; count < 32;  count++)
    {
        if (IS_SET(bint,1<<count)
	&& !IS_SET(aint,1<<count))
        {
            if (count < 26)
                buf[pos] = 'A' + count;
            else
                buf[pos] = 'a' + (count - 26);
            pos++;
        }
    }

    if (pos == 0)
    {
        buf[pos] = '0';
        pos++;
    }

    buf[pos] = '\0';

    return buf;
}

void print_debug( int pos, const char *string )
{
    int i;

    if (!debug)
	return;

    for (i = 0; i < pos; i++)
    {
	printf("\t");
    }
    printf("%s\n", string);
    return;
}

void save_area( FILE *fp )
{
    printf("Saving AREA.\n");

    fprintf( fp, "#AREA\n"						);
    fprintf( fp, "ROT v1.5 format~\n"					);
    fprintf( fp, "%s~\n", area_first->file_name				);
    fprintf( fp, "%s~\n", area_first->name				);
    fprintf( fp, "%s~\n", area_first->credits				);
    fprintf( fp, "%d %d\n", newmin, newmax				);

    return;
}

void save_helps( FILE *fp )
{
    HELP_DATA *pHelp;

    if ( help_first == NULL )
	return;

    printf("Saving HELPS.\n");
    fprintf( fp, "\n#HELPS\n"						);

    for (pHelp = help_first; pHelp != NULL; pHelp = pHelp->next)
    {
	fprintf( fp, "%d ", pHelp->level				);
	fprintf( fp, "%s~\n", pHelp->keyword				);
	fprintf( fp, "%s~\n", pHelp->text				);
    }
    fprintf( fp, "0 $~\n" );
    return;
}

void save_mobiles( FILE *fp )
{
    MOB_INDEX_DATA *pMobIndex;
    int vnum;

    printf("Saving MOBILES.\n");
    fprintf( fp, "\n#MOBILES\n"						);

    for (vnum = first_mobile; vnum <= last_mobile; vnum++ )
    {
	if ( ( pMobIndex = get_mob_index( vnum ) ) != NULL )
	{
	    char buf[MAX_STRING_LENGTH];
	    char buf2[MAX_STRING_LENGTH];
	    sh_int race;

	    sprintf(buf,"%d",pMobIndex->vnum);
	    print_debug(1,buf);

	    sprintf(buf, "%c%c", 10, 13 );
	    sprintf(buf2, "%c", 10 );

	    if (changevnum)
		fprintf( fp, "#%d\n", pMobIndex->vnum + newvnum		);
	    else
		fprintf( fp, "#%d\n", pMobIndex->vnum			);
	    print_debug(2,"Saving player_name");
	    str_replace(pMobIndex->player_name, buf, buf2);
	    fprintf( fp, "%s~\n", pMobIndex->player_name		);
	    print_debug(2,"Saving short_descr");
	    str_replace(pMobIndex->short_descr, buf, buf2);
	    fprintf( fp, "%s~\n", pMobIndex->short_descr		);
	    print_debug(2,"Saving long_descr");
	    str_replace(pMobIndex->long_descr, buf, buf2);
	    fprintf( fp, "%s~\n", pMobIndex->long_descr			);
	    print_debug(2,"Saving description");
	    str_replace(pMobIndex->description, buf, buf2);
	    fprintf( fp, "%s~\n", pMobIndex->description		);
	    print_debug(2,"Saving race");
	    fprintf( fp, "%s~\n", race_table[pMobIndex->race].name	);
	    race = pMobIndex->race;
	    print_debug(2,"Saving act flags");
	    fprintf( fp, "%s ", print_flags(pMobIndex->act)		);
	    print_debug(2,"Saving affect flags");
	    fprintf( fp, "%s ", print_flags(pMobIndex->affected_by)	);
	    print_debug(2,"Saving shield flags");
	    fprintf( fp, "%s ", print_flags(pMobIndex->shielded_by)	);
	    print_debug(2,"Saving alignment");
	    fprintf( fp, "%d ", pMobIndex->alignment			);
	    print_debug(2,"Saving group");
	    fprintf( fp, "%d\n", pMobIndex->group			);
	    print_debug(2,"Saving level");
	    fprintf( fp, "%d ", pMobIndex->level			);
	    print_debug(2,"Saving hitroll");
	    fprintf( fp, "%d ", pMobIndex->hitroll			);
	    print_debug(2,"Saving HP");
	    fprintf( fp, "%d", pMobIndex->hit[DICE_NUMBER]		);
	    fprintf( fp, "d"						);
	    fprintf( fp, "%d", pMobIndex->hit[DICE_TYPE]		);
	    fprintf( fp, "+"						);
	    fprintf( fp, "%d ", pMobIndex->hit[DICE_BONUS]		);
	    print_debug(2,"Saving mana");
	    fprintf( fp, "%d", pMobIndex->mana[DICE_NUMBER]		);
	    fprintf( fp, "d"						);
	    fprintf( fp, "%d", pMobIndex->mana[DICE_TYPE]		);
	    fprintf( fp, "+"						);
	    fprintf( fp, "%d ", pMobIndex->mana[DICE_BONUS]		);
	    print_debug(2,"Saving damage");
	    fprintf( fp, "%d", pMobIndex->damage[DICE_NUMBER]		);
	    fprintf( fp, "d"						);
	    fprintf( fp, "%d", pMobIndex->damage[DICE_TYPE]		);
	    fprintf( fp, "+"						);
	    fprintf( fp, "%d ", pMobIndex->damage[DICE_BONUS]		);
	    print_debug(2,"Saving damage type");
	    fprintf( fp, "%s\n", attack_table[pMobIndex->dam_type].name	);
	    print_debug(2,"Saving AC");
	    fprintf( fp, "%d ", pMobIndex->ac[AC_PIERCE]/10		);
	    fprintf( fp, "%d ", pMobIndex->ac[AC_BASH]/10		);
	    fprintf( fp, "%d ", pMobIndex->ac[AC_SLASH]/10		);
	    fprintf( fp, "%d\n", pMobIndex->ac[AC_EXOTIC]/10		);
	    print_debug(2,"Saving offense flags");
	    fprintf( fp, "%s ", print_flags(pMobIndex->off_flags)	);
	    print_debug(2,"Saving immune flags");
	    fprintf( fp, "%s ", print_flags(pMobIndex->imm_flags)	);
	    print_debug(2,"Saving resist flags");
	    fprintf( fp, "%s ", print_flags(pMobIndex->res_flags)	);
	    print_debug(2,"Saving vulnerable flags");
	    fprintf( fp, "%s\n", print_flags(pMobIndex->vuln_flags)	);
	    print_debug(2,"Saving start position");
	    fprintf( fp, "%s ",
		position_table[pMobIndex->start_pos].short_name		);
	    print_debug(2,"Saving default position");
	    fprintf( fp, "%s ",
		position_table[pMobIndex->default_pos].short_name	);
	    print_debug(2,"Saving sex");
	    fprintf( fp, "%s ", sex_table[pMobIndex->sex].name		);
	    print_debug(2,"Saving wealth");
	    fprintf( fp, "%ld\n", pMobIndex->wealth			);
	    print_debug(2,"Saving form flags");
	    fprintf( fp, "%s ", print_flags(pMobIndex->form)		);
	    print_debug(2,"Saving parts flags");
	    fprintf( fp, "%s ", print_flags(pMobIndex->parts)		);
	    print_debug(2,"Saving size");
	    fprintf( fp, "%s ", size_table[pMobIndex->size].name	);
	    print_debug(2,"Saving material");
	    if (str_infix( " ", pMobIndex->material ) )
		fprintf( fp, "%s\n", pMobIndex->material		);
	    else
		fprintf( fp, "'%s'\n", pMobIndex->material		);
	    if (pMobIndex->die_descr[0] != '\0')
	    {
		print_debug(2,"Saving die message");
		str_replace(pMobIndex->die_descr, buf, buf2);
		fprintf( fp, "D %s~\n", pMobIndex->die_descr		);
	    }
	    if (pMobIndex->say_descr[0] != '\0')
	    {
		print_debug(3,"Saving say message");
		str_replace(pMobIndex->say_descr, buf, buf2);
		fprintf( fp, "T %s~\n", pMobIndex->say_descr		);
	    }
	    if (pMobIndex->clan[0] != '\0')
	    {
		print_debug(3,"Saving clan");
		str_replace(pMobIndex->clan, buf, buf2);
		fprintf( fp, "C %s~\n", pMobIndex->clan			);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->act,race_table[race].act ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F act %s\n", buf				);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->affected_by,race_table[race].aff ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F aff %s\n", buf				);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->shielded_by,race_table[race].shd ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F shd %s\n", buf				);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->off_flags,race_table[race].off ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F off %s\n", buf				);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->imm_flags,race_table[race].imm ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F imm %s\n", buf				);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->res_flags,race_table[race].res ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F res %s\n", buf				);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->vuln_flags,race_table[race].vuln ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F vul %s\n", buf				);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->form,race_table[race].form ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F for %s\n", buf				);
	    }
	    buf[0] = '\0';
	    sprintf(buf,"%s",
		cmp_flags( pMobIndex->parts,race_table[race].parts ) );
	    if (buf[0] != '0')
	    {
		print_debug(3,"Saving flag remove");
		fprintf( fp, "F par %s\n", buf				);
	    }
	}
    }
    fprintf( fp, "#0\n" );
    return;
}

void save_rooms( FILE *fp )
{
    ROOM_INDEX_DATA *pRoomIndex;
    int vnum;

    printf("Saving ROOMS.\n");
    fprintf( fp, "\n#ROOMS\n"						);

    for (vnum = first_room; vnum <= last_room; vnum++ )
    {
	if ( ( pRoomIndex = get_room_index( vnum ) ) != NULL )
	{
	    char buf[MAX_STRING_LENGTH];
	    char buf2[MAX_STRING_LENGTH];
	    GUILD_DATA *guild;
	    RACE_DATA *race;
	    EXTRA_DESCR_DATA *ed;
	    int door;

	    sprintf(buf,"%d",pRoomIndex->vnum);
	    print_debug(1,buf);

	    sprintf(buf, "%c%c", 10, 13 );
	    sprintf(buf2, "%c", 10 );

	    if (changevnum)
		fprintf( fp, "#%d\n", pRoomIndex->vnum + newvnum	);
	    else
		fprintf( fp, "#%d\n", pRoomIndex->vnum			);
	    print_debug(2,"Saving name");
	    str_replace(pRoomIndex->name, buf, buf2);
	    fprintf( fp, "%s~\n", pRoomIndex->name			);
	    print_debug(2,"Saving description");
	    str_replace(pRoomIndex->description, buf, buf2);
	    fprintf( fp, "%s~\n", pRoomIndex->description		);
	    print_debug(2,"Saving room flags");
	    fprintf( fp, "0 %s ", print_flags(pRoomIndex->room_flags)	);
	    print_debug(2,"Saving sector type");
	    fprintf( fp, "%d\n", pRoomIndex->sector_type		);
	    for ( door = 0; door <= 11; door++ )
	    {
		EXIT_DATA *pexit;

		if ( ( pexit = pRoomIndex->exit[door] ) != NULL)
		{
		    int locks;

		    print_debug(3,"Saving door");
		    fprintf( fp, "D%d\n", door				);
		    print_debug(4,"Saving description");
		    str_replace(pexit->description, buf, buf2);
		    fprintf( fp, "%s~\n", pexit->description		);
		    print_debug(4,"Saving keyword");
		    str_replace(pexit->keyword, buf, buf2);
		    fprintf( fp, "%s~\n", pexit->keyword		);
		    print_debug(4,"Saving door flags");
		    if (pexit->exit_info == EX_ISDOOR)
			locks = 1;
		    else if (pexit->exit_info == (EX_ISDOOR | EX_PICKPROOF))
			locks = 2;
		    else if (pexit->exit_info == (EX_ISDOOR | EX_NOPASS))
			locks = 3;
		    else if (pexit->exit_info == (EX_ISDOOR | EX_NOPASS | EX_PICKPROOF))
			locks = 4;
		    else
			locks = 0;
		    fprintf(fp,"%d ", locks				);
		    if (changevnum)
		    {
			if ((pexit->key >= area_first->min_vnum)
			&&  (pexit->key <= area_first->max_vnum))
			    fprintf(fp,"%d ", pexit->key + newvnum	);
			else
			    fprintf(fp,"%d ", pexit->key		);
			if ((pexit->u1.vnum >= area_first->min_vnum)
			&&  (pexit->u1.vnum <= area_first->max_vnum))
			    fprintf(fp,"%d\n", pexit->u1.vnum + newvnum	);
			else
			    fprintf(fp,"%d\n", pexit->u1.vnum		);
		    } else {
			fprintf(fp,"%d ", pexit->key			);
			fprintf(fp,"%d\n", pexit->u1.vnum		);
		    }
		}
	    }
	    if ((pRoomIndex->heal_rate != 100)
	    || (pRoomIndex->mana_rate != 100))
	    {
		print_debug(3,"Saving heal/mana");
		fprintf( fp, "M %d ", pRoomIndex->mana_rate		);
		fprintf( fp, "H %d\n", pRoomIndex->heal_rate		);
	    }
	    if (pRoomIndex->clan[0] != '\0')
	    {
		print_debug(3,"Saving clan");
		str_replace(pRoomIndex->clan, buf, buf2);
		fprintf( fp, "C %s~\n", pRoomIndex->clan		);
	    }
	    for (guild = pRoomIndex->guild; guild != NULL; guild = guild->next)
	    {
		print_debug(3,"Saving guild");
		fprintf( fp, "G %s~\n", class_table[guild->guild].name	);
	    }
	    for (race = pRoomIndex->race; race != NULL; race = race->next)
	    {
		print_debug(3,"Saving race");
		fprintf( fp, "R %s~\n", race_table[race->race].name	);
	    }
	    if (pRoomIndex->owner[0] != '\0')
	    {
		print_debug(3,"Saving owner");
		str_replace(pRoomIndex->owner, buf, buf2);
		fprintf( fp, "O %s~\n", pRoomIndex->owner		);
	    }
	    for (ed = pRoomIndex->extra_descr; ed != NULL; ed = ed->next)
	    {
		print_debug(3,"Saving extra description");
		fprintf( fp, "E\n"					);
		str_replace(ed->keyword, buf, buf2);
		fprintf( fp, "%s~\n", ed->keyword			);
		str_replace(ed->description, buf, buf2);
		fprintf( fp, "%s~\n", ed->description			);
	    }
	    fprintf( fp, "S\n"						);
	}
    }
    fprintf( fp, "#0\n"							);
    return;
}

void save_objects( FILE *fp )
{
    OBJ_INDEX_DATA *pObjIndex;
    int vnum;

    printf("Saving OBJECTS.\n");
    fprintf( fp, "\n#OBJECTS\n"						);

    for (vnum = first_object; vnum <= last_object; vnum++ )
    {
	if ( ( pObjIndex = get_obj_index( vnum ) ) != NULL )
	{
	    char buf[MAX_STRING_LENGTH];
	    char buf2[MAX_STRING_LENGTH];
	    GUILD_DATA *guild;
	    EXTRA_DESCR_DATA *ed;
	    AFFECT_DATA *paf;
	    int condition;

	    sprintf(buf,"%d",pObjIndex->vnum);
	    print_debug(1,buf);

	    sprintf(buf, "%c%c", 10, 13 );
	    sprintf(buf2, "%c", 10 );

	    if (changevnum)
		fprintf( fp, "#%d\n", pObjIndex->vnum + newvnum		);
	    else
		fprintf( fp, "#%d\n", pObjIndex->vnum			);
	    print_debug(2,"Saving name");
	    str_replace(pObjIndex->name, buf, buf2);
	    fprintf( fp, "%s~\n", pObjIndex->name			);
	    print_debug(2,"Saving short_descr");
	    str_replace(pObjIndex->short_descr, buf, buf2);
	    fprintf( fp, "%s~\n", pObjIndex->short_descr		);
	    print_debug(2,"Saving description");
	    str_replace(pObjIndex->description, buf, buf2);
	    fprintf( fp, "%s~\n", pObjIndex->description		);
	    print_debug(2,"Saving material");
	    str_replace(pObjIndex->material, buf, buf2);
	    fprintf( fp, "%s~\n", pObjIndex->material			);
	    print_debug(2,"Saving item type");
	    fprintf( fp, "%s ", item_table[pObjIndex->item_type].name	);
	    print_debug(2,"Saving extra flags");
	    fprintf( fp, "%s ", print_flags(pObjIndex->extra_flags)	);
	    print_debug(2,"Saving wear flags");
	    fprintf( fp, "%s\n", print_flags(pObjIndex->wear_flags)	);

	    print_debug(2,"Saving v0-v4");
	switch(pObjIndex->item_type)
	{
	case ITEM_WEAPON:
	    fprintf( fp, "%s ", weapon_table[pObjIndex->value[0]].name	);
	    fprintf( fp, "%d ", pObjIndex->value[1]			);
	    fprintf( fp, "%d ", pObjIndex->value[2]			);
	    fprintf( fp, "%s ", attack_table[pObjIndex->value[3]].name	);
	    fprintf( fp, "%s\n", print_flags(pObjIndex->value[4])	);
	    break;
	case ITEM_CONTAINER:
	case ITEM_PIT:
	    fprintf( fp, "%d ", pObjIndex->value[0]			);
	    fprintf( fp, "%s ", print_flags(pObjIndex->value[1])	);
	    if (changevnum)
	    {
		if ((pObjIndex->value[2] >= area_first->min_vnum)
		&&  (pObjIndex->value[2] <= area_first->max_vnum))
		    fprintf( fp, "%d ", pObjIndex->value[2] + newvnum	);
		else
		    fprintf( fp, "%d ", pObjIndex->value[2]		);
	    }
	    fprintf( fp, "%d ", pObjIndex->value[3]			);
	    fprintf( fp, "%d\n", pObjIndex->value[4]			);
	    break;
	case ITEM_EXIT:
	    if (changevnum)
	    {
		if ((pObjIndex->value[0] >= area_first->min_vnum)
		&&  (pObjIndex->value[0] <= area_first->max_vnum))
		    fprintf( fp, "%d ", pObjIndex->value[0] + newvnum	);
		else
		    fprintf( fp, "%d ", pObjIndex->value[0]		);
	    }
	    fprintf( fp, "%d ", pObjIndex->value[1]			);
	    fprintf( fp, "%d ", pObjIndex->value[2]			);
	    fprintf( fp, "%d ", pObjIndex->value[3]			);
	    fprintf( fp, "%d\n", pObjIndex->value[4]			);
	    break;
	case ITEM_PORTAL:
	    fprintf( fp, "%d ", pObjIndex->value[0]			);
	    fprintf( fp, "%d ", pObjIndex->value[1]			);
	    fprintf( fp, "%s ", print_flags(pObjIndex->value[2])	);
	    if (changevnum)
	    {
		if ((pObjIndex->value[3] >= area_first->min_vnum)
		&&  (pObjIndex->value[3] <= area_first->max_vnum))
		    fprintf( fp, "%d ", pObjIndex->value[3] + newvnum	);
		else
		    fprintf( fp, "%d ", pObjIndex->value[3]		);
	    }
	    fprintf( fp, "%d\n", pObjIndex->value[4]			);
            break;
        case ITEM_DRINK_CON:
	case ITEM_FOUNTAIN:
	    fprintf( fp, "%d ", pObjIndex->value[0]			);
	    fprintf( fp, "%d ", pObjIndex->value[1]			);
	    fprintf( fp, "'%s' ", liq_table[pObjIndex->value[2]].liq_name);
	    fprintf( fp, "%d ", pObjIndex->value[3]			);
	    fprintf( fp, "%d\n", pObjIndex->value[4]			);
            break;
	case ITEM_WAND:
	case ITEM_STAFF:
	    fprintf( fp, "%d ", pObjIndex->value[0]			);
	    fprintf( fp, "%d ", pObjIndex->value[1]			);
	    fprintf( fp, "%d ", pObjIndex->value[2]			);
	    fprintf( fp, "'%s' ", skill_table[pObjIndex->value[3]].name	);
	    fprintf( fp, "%d\n", pObjIndex->value[4]			);
	    break;
	case ITEM_POTION:
	case ITEM_PILL:
	case ITEM_SCROLL:
	    fprintf( fp, "%d ", pObjIndex->value[0]			);
	    fprintf( fp, "'%s' ", skill_table[pObjIndex->value[1]].name	);
	    fprintf( fp, "'%s' ", skill_table[pObjIndex->value[2]].name	);
	    fprintf( fp, "'%s' ", skill_table[pObjIndex->value[3]].name	);
	    fprintf( fp, "'%s'\n", skill_table[pObjIndex->value[4]].name);
	    break;
	default:
	    fprintf( fp, "%d ", pObjIndex->value[0]			);
	    fprintf( fp, "%d ", pObjIndex->value[1]			);
	    fprintf( fp, "%d ", pObjIndex->value[2]			);
	    fprintf( fp, "%d ", pObjIndex->value[3]			);
	    fprintf( fp, "%d\n", pObjIndex->value[4]			);
	    break;
	}
	    print_debug(2,"Saving level");
	    fprintf( fp, "%d ", pObjIndex->level			);
	    print_debug(2,"Saving weight");
	    fprintf( fp, "%d ", pObjIndex->weight			);
	    print_debug(2,"Saving cost");
	    fprintf( fp, "%d ", pObjIndex->cost				);
	    print_debug(2,"Saving condition");
	    condition = pObjIndex->condition;
	    if (condition >= 100)
		fprintf( fp, "P\n"					);
	    else if (condition >= 90)
		fprintf( fp, "G\n"					);
	    else if (condition >= 75)
		fprintf( fp, "A\n"					);
	    else if (condition >= 50)
		fprintf( fp, "W\n"					);
	    else if (condition >= 25)
		fprintf( fp, "D\n"					);
	    else if (condition >= 10)
		fprintf( fp, "B\n"					);
	    else if (condition >= 0)
		fprintf( fp, "R\n"					);
	    else
		fprintf( fp, "P\n"					);
	    if (pObjIndex->clan[0] != '\0')
	    {
		print_debug(3,"Saving clan");
		str_replace(pObjIndex->clan, buf, buf2);
		fprintf( fp, "C %s~\n", pObjIndex->clan			);
	    }
	    for (guild = pObjIndex->guild; guild != NULL; guild = guild->next)
	    {
		print_debug(3,"Saving guild");
		fprintf( fp, "G %s~\n", class_table[guild->guild].name	);
	    }
	    for (paf = pObjIndex->affected; paf != NULL; paf = paf->next)
	    {
		if (paf->bitvector == 0)
		{
		    print_debug(3,"Saving affect");
		    fprintf( fp, "A\n"					);
		    fprintf( fp, "%d ", paf->location			);
		    fprintf( fp, "%d\n", paf->modifier			);
		} else
		{
		    print_debug(3,"Saving flags");
		    fprintf( fp, "F\n"					);
		    if (paf->where == TO_AFFECTS)
			fprintf( fp, "A "				);
		    else if (paf->where == TO_IMMUNE)
			fprintf( fp, "I "				);
		    else if (paf->where == TO_RESIST)
			fprintf( fp, "R "				);
		    else if (paf->where == TO_VULN)
			fprintf( fp, "V "				);
		    else if (paf->where == TO_SHIELDS)
			fprintf( fp, "S "				);
		    fprintf( fp, "%d ", paf->location			);
		    fprintf( fp, "%d ", paf->modifier			);
		    fprintf( fp, "%s\n", print_flags(paf->bitvector)	);
		}
	    }
	    for (ed = pObjIndex->extra_descr; ed != NULL; ed = ed->next)
	    {
		print_debug(3,"Saving extra description");
		fprintf( fp, "E\n"					);
		str_replace(ed->keyword, buf, buf2);
		fprintf( fp, "%s~\n", ed->keyword			);
		str_replace(ed->description, buf, buf2);
		fprintf( fp, "%s~\n", ed->description			);
	    }
	}
    }
    fprintf( fp, "#0\n"							);
    return;
}

void save_shops( FILE *fp )
{
    MOB_INDEX_DATA *pMobIndex;
    int vnum;

    printf("Saving SHOPS.\n");
    fprintf( fp, "\n#SHOPS\n"						);

    for (vnum = first_mobile; vnum <= last_mobile; vnum++ )
    {
	if ( ( pMobIndex = get_mob_index( vnum ) ) != NULL )
	{
	    SHOP_DATA *pShop;

	    if ( ( pShop = pMobIndex->pShop ) != NULL )
	    {
		int iTrade;
		char buf[MAX_STRING_LENGTH];
		char buf2[MAX_STRING_LENGTH];

		sprintf(buf, "%c%c", 10, 13 );
		sprintf(buf2, "%c", 10 );

		if (changevnum)
		    fprintf( fp, "%-7d", pShop->keeper + newvnum	);
		else
		    fprintf( fp, "%-7d", pShop->keeper			);
		for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ )
		    fprintf( fp, "%4d", pShop->buy_type[iTrade]	);
		fprintf( fp, "%7d", pShop->profit_buy			);
		fprintf( fp, "%5d", pShop->profit_sell			);
		fprintf( fp, "%5d", pShop->open_hour			);
		fprintf( fp, "%3d", pShop->close_hour			);
		fprintf( fp, "    * "					);
		str_replace(pMobIndex->short_descr, buf, buf2);
		fprintf( fp, "%s\n", pMobIndex->short_descr		);
	    }
	}
    }
    fprintf( fp, "0\n"							);
    return;
}

void save_resets( FILE *fp )
{
    RESET_DATA *pReset;
    int last;
    char buf[MAX_STRING_LENGTH];
    char buf2[MAX_STRING_LENGTH];
    bool found;

    sprintf(buf, "%c%c", 10, 13 );
    sprintf(buf2, "%c", 10 );

    printf("Saving RESETS.\n");
    fprintf( fp, "\n#RESETS\n"						);

    last = 0;

    found = FALSE;
   for (pReset = area_first->reset_first; pReset != NULL; pReset = pReset->next)
    {
	ROOM_INDEX_DATA *pRoomIndex;

	switch( pReset->command )
	{
	default:
	    break;

	case 'D':
	    found = TRUE;
	    fprintf( fp, "D 0 "						);
	    if (changevnum)
		fprintf( fp, "%5d ", pReset->arg1 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg1			);
	    fprintf( fp, "%3d ", pReset->arg2				);
	    fprintf( fp, "%1d            * ", pReset->arg3		);
	    if ( ( pRoomIndex = get_room_index( pReset->arg1 ) ) != NULL )
	    {
		str_replace(pRoomIndex->name, buf, buf2);
		fprintf( fp, "%s\n", pRoomIndex->name			);
	    } else
	    {
		fprintf( fp, "\n"					);
	    }
	    break;
	}
    }
    if (found)
	fprintf( fp, "\n"						);
    found = FALSE;
   for (pReset = area_first->reset_first; pReset != NULL; pReset = pReset->next)
    {
	ROOM_INDEX_DATA *pRoomIndex;

	switch( pReset->command )
	{
	default:
	    break;

	case 'R':
	    found = TRUE;
	    fprintf( fp, "R 0 "						);
	    if (changevnum)
		fprintf( fp, "%5d ", pReset->arg1 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg1			);
	    fprintf( fp, "%3d  ", pReset->arg2				);
	    fprintf( fp, "            * "				);
	    if ( ( pRoomIndex = get_room_index( pReset->arg1 ) ) != NULL )
	    {
		str_replace(pRoomIndex->name, buf, buf2);
		fprintf( fp, "%s\n", pRoomIndex->name			);
	    } else
	    {
		fprintf( fp, "\n"					);
	    }
	    break;
	}
    }
    if (found)
	fprintf( fp, "\n"						);
    found = FALSE;
   for (pReset = area_first->reset_first; pReset != NULL; pReset = pReset->next)
    {
	OBJ_INDEX_DATA *pObjIndex;

	switch( pReset->command )
	{
	default:
	    last = 0;
	    break;

	case 'O':
	    found = TRUE;
	    last = 1;
	    fprintf( fp, "O 0 "						);
	    if ((changevnum)
	    &&  (pReset->arg1 >= area_first->min_vnum)
	    &&  (pReset->arg1 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg1 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg1			);
	    fprintf( fp, "%3d ", pReset->arg2				);
	    if ((changevnum)
	    &&  (pReset->arg3 >= area_first->min_vnum)
	    &&  (pReset->arg3 <= area_first->max_vnum))
		fprintf( fp, "%5d        * ", pReset->arg3 + newvnum	);
	    else
		fprintf( fp, "%5d        * ", pReset->arg3		);
	    if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) != NULL )
	    {
		str_replace(pObjIndex->short_descr, buf, buf2);
		fprintf( fp, "%s\n", pObjIndex->short_descr		);
	    } else
	    {
		fprintf( fp, "\n"					);
	    }
	    break;

	case 'P':
	    if (last == 0)
		break;
	    found = TRUE;
	    fprintf( fp, "P 0 "						);
	    if ((changevnum)
	    &&  (pReset->arg1 >= area_first->min_vnum)
	    &&  (pReset->arg1 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg1 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg1			);
	    fprintf( fp, "%3d ", pReset->arg2				);
	    if ((changevnum)
	    &&  (pReset->arg3 >= area_first->min_vnum)
	    &&  (pReset->arg3 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg3 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg3			);
	    fprintf( fp, "%3d    *   ", pReset->arg4			);
	    if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) != NULL )
	    {
		str_replace(pObjIndex->short_descr, buf, buf2);
		fprintf( fp, "%s\n", pObjIndex->short_descr		);
	    } else
	    {
		fprintf( fp, "\n"					);
	    }
	    break;
	}
    }
     if (found)
	fprintf( fp, "\n"						);
    found = FALSE;

   for (pReset = area_first->reset_first; pReset != NULL; pReset = pReset->next)
    {
	MOB_INDEX_DATA *pMobIndex;
	OBJ_INDEX_DATA *pObjIndex;

	switch( pReset->command )
	{
	default:
	    last = 0;
	    break;

	case 'M':
	    found = TRUE;
	    last = 0;
	    fprintf( fp, "M 0 "						);
	    if ((changevnum)
	    &&  (pReset->arg1 >= area_first->min_vnum)
	    &&  (pReset->arg1 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg1 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg1			);
	    fprintf( fp, "%3d ", pReset->arg2				);
	    if ((changevnum)
	    &&  (pReset->arg3 >= area_first->min_vnum)
	    &&  (pReset->arg3 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg3 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg3			);
	    fprintf( fp, "%3d    * ", pReset->arg4			);
	    if ( ( pMobIndex = get_mob_index( pReset->arg1 ) ) != NULL )
	    {
		str_replace(pMobIndex->short_descr, buf, buf2);
		fprintf( fp, "%s\n", pMobIndex->short_descr		);
	    } else
	    {
		fprintf( fp, "\n"					);
	    }
	    break;

	case 'E':
	    found = TRUE;
	    last = 1;
	    fprintf( fp, "E 0 "						);
	    if ((changevnum)
	    &&  (pReset->arg1 >= area_first->min_vnum)
	    &&  (pReset->arg1 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg1 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg1			);
	    fprintf( fp, "%3d ", pReset->arg2				);
	    fprintf( fp, "%2d           *   ", pReset->arg3		);
	    if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) != NULL )
	    {
		str_replace(pObjIndex->name, buf, buf2);
		fprintf( fp, "%s\n", pObjIndex->short_descr		);
	    } else
	    {
		fprintf( fp, "\n"					);
	    }
	    break;

	case 'G':
	    found = TRUE;
	    last = 1;
	    fprintf( fp, "G 0 "						);
	    if ((changevnum)
	    &&  (pReset->arg1 >= area_first->min_vnum)
	    &&  (pReset->arg1 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg1 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg1			);
	    fprintf( fp, "%3d  ", pReset->arg2				);
	    fprintf( fp, "            *   "				);
	    if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) != NULL )
	    {
		str_replace(pObjIndex->name, buf, buf2);
		fprintf( fp, "%s\n", pObjIndex->short_descr		);
	    } else
	    {
		fprintf( fp, "\n"					);
	    }
	    break;

	case 'P':
	    if (last == 0)
		break;
	    found = TRUE;
	    fprintf( fp, "P 0 "						);
	    if ((changevnum)
	    &&  (pReset->arg1 >= area_first->min_vnum)
	    &&  (pReset->arg1 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg1 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg1			);
	    fprintf( fp, "%3d ", pReset->arg2				);
	    if ((changevnum)
	    &&  (pReset->arg3 >= area_first->min_vnum)
	    &&  (pReset->arg3 <= area_first->max_vnum))
		fprintf( fp, "%5d ", pReset->arg3 + newvnum		);
	    else
		fprintf( fp, "%5d ", pReset->arg3			);
	    fprintf( fp, "%3d    *     ", pReset->arg4			);
	    if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) != NULL )
	    {
		str_replace(pObjIndex->short_descr, buf, buf2);
		fprintf( fp, "%s\n", pObjIndex->short_descr		);
	    } else
	    {
		fprintf( fp, "\n"					);
	    }
	    break;
	}
    }
    if (found)
	fprintf( fp, "\n"						);
    found = FALSE;

    fprintf( fp, "S\n"							);
    return;
}

void save_specials( FILE *fp )
{
    MOB_INDEX_DATA *pMobIndex;
    int vnum;

    printf("Saving SPECIALS.\n");
    fprintf( fp, "\n#SPECIALS\n"					);

    for (vnum = first_mobile; vnum <= last_mobile; vnum++ )
    {
	if ( ( pMobIndex = get_mob_index( vnum ) ) != NULL )
	{
	    if ( pMobIndex->spec_fun != NULL )
	    {
		char buf[MAX_STRING_LENGTH];
		char buf2[MAX_STRING_LENGTH];

		sprintf(buf, "%c%c", 10, 13 );
		sprintf(buf2, "%c", 10 );

		fprintf( fp, "M "					);
		if ((changevnum)
		&&  (vnum >= area_first->min_vnum)
		&&  (vnum <= area_first->max_vnum))
		    fprintf( fp, "%5d ", vnum + newvnum			);
		else
		    fprintf( fp, "%5d ", vnum				);
		fprintf( fp, "%-30s * ", pMobIndex->spec_fun		);
		str_replace(pMobIndex->short_descr, buf, buf2);
		fprintf( fp, "%s\n", pMobIndex->short_descr		);
	    }
	}
    }
    fprintf( fp, "S\n"							);
    return;
}

void save_dreams( FILE *fp )
{
    DRM_INDEX_DATA *pDrmIndex;
    int vnum;

    if (drm_index == NULL)
	return;

    printf("Saving DREAMS.\n");
    fprintf( fp, "\n#DREAMS\n"						);

    vnum = newmin;

    for (pDrmIndex = drm_index; pDrmIndex != NULL; pDrmIndex = pDrmIndex->next )
    {
	char buf[MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	DREAM_ACT_DATA *pat;
	DREAM_CHANGE_DATA *pch;
	DREAM_OBJECT_DATA *pob;

	sprintf(buf, "%c%c", 10, 13 );
	sprintf(buf2, "%c", 10 );

	fprintf( fp, "#%d\n", vnum					);
	str_replace(pDrmIndex->description, buf, buf2);
	fprintf( fp, "%s~\n", pDrmIndex->description			);
	for (pat = pDrmIndex->act; pat != NULL; pat = pat->next)
	{
	    str_replace(pat->string, buf, buf2);
	    fprintf( fp, "A %s~\n", pat->string				);
	}
	if (pDrmIndex->move)
	    fprintf( fp, "M %d\n", pDrmIndex->move			);
	for (pch = pDrmIndex->change; pch != NULL; pch = pch->next)
	    fprintf( fp, "C %s %s\n", pch->keyword, pch->value		);
	for (pob = pDrmIndex->object; pob != NULL; pob = pob->next)
	{
	    fprintf( fp, "O %d %s ", pob->vnum, pob->roomchar		);
	    fprintf( fp, "%d ", pob->variable				);
	    fprintf( fp, "%d %d\n", pob->t_min, pob->t_max		);
	}
	fprintf( fp, "S\n"						);
	vnum++;
    }
    fprintf( fp, "#0\n"							);
    return;
}