/**************************************************************************
* ROM Area Export - Will save Dawn/DOT Area Files to ROM Format           *
* Re-coded from ROM 2.4 by Brad Wilson (Ixliam) Copyright (c) 2006.       * 
* To use this code, you must follow all relavent licences below and leave *
* this credit intact. If you find this useful, please let me know.        *                                      
***************************************************************************
* >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer,       *
*    Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe.   *
* >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael       *
*    Chastain, Michael Quan, and Mitchell Tse.                            *
* >> ROM 2.4 is copyright 1993-1995 Russ Taylor and 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) *
***************************************************************************/

/**************************************************************************
 This small piece of code is usefull to drop into the end of obdb.cpp. 
 Just add the command do_romexport to your interp.h and interp.cpp files, 
 and you can export your areas out to ROM or SD/DRM (use the savesd 
 routines). If you like this code or improve it, please drop me a line 
 at ixliam <AT> wotl <DOT> org. Some tweaking may be required for your
 particular flavor of ROM, as well as removing anything specific to my 
 own mud.
***************************************************************************/

char *fwrite_flags( long flags, char buf[] )
{
    char offset;
    char *cp;

	static char local_buf[33];
	if(buf==NULL){
		buf=local_buf;
	}
	
	buf[0] = '\0';
	
	if ( flags == 0 )
    {
		strcpy( buf, "0" );
		return buf;
    }
	
    /* 32 -- number of bits in a long */
	
    for ( offset = 0, cp = buf; offset < 32; offset++ ){
		if ( flags & ( (long)1 << offset ) )
		{
			if ( offset <= 'Z' - 'A' ){
				*(cp++) = 'A' + offset;
			}else{
				*(cp++) = 'a' + offset - ( 'Z' - 'A' + 1 );
			}
		}
	}
		
	*cp = '\0';
	
	return buf;
}
/**************************************************************************/
void saverom_mobprogs(FILE * fp, AREA_DATA * pArea)
{
	MPROG_CODE *pMprog;
	int i;

	fprintf(fp, "#MOBPROGS\n");

	for (i = pArea->min_vnum; i <= pArea->max_vnum; i++)
	{
		if ( (pMprog = get_mprog_index(i) ) != NULL)
		{
			fprintf(fp, "#%d\n", i);
			fprintf(fp, "%s~\n", fix_string(pMprog->code));
		}
	}

	fprintf(fp, "#0\n\n");
	return;
}
/**************************************************************************/
void saverom_mobile(FILE *fp, MOB_INDEX_DATA *pMobIndex)
{
    	sh_int race = pMobIndex->race;
    	MPROG_LIST *pMprog;
	int align = 0;
	char buf[MSL];

	fprintf(fp, "#%d\n", pMobIndex->vnum);
	fprintf(fp, "%s~\n", pMobIndex->player_name);
	fprintf(fp, "%s~\n", pMobIndex->short_descr);
	fprintf(fp, "%s\n~\n", fix_string(pMobIndex->long_descr));
	fprintf(fp, "%s~\n", fix_string(pMobIndex->description));
	fprintf(fp, "%s~\n", race_table[race]->name);
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->act, buf));
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->affected_by, buf));

    	switch(pMobIndex->alliance)
    	{
		case 3:
			align = 600;
			break;
		case 2:
			align = 400;
			break;
		case 1:
			align = 200;
			break;
		case 0:
			align = 0;
			break;
		case -1:
			align = -200;
			break;
		case -2:
			align = -400;
			break;
		case -3:
			align = -600;
			break;
	}
	fprintf(fp, "%d 0\n", align);
	fprintf(fp, "%d %d ", pMobIndex->level, pMobIndex->hitroll);
	fprintf(fp, "%dd%d+%d ", pMobIndex->hit[DICE_NUMBER],
			         pMobIndex->hit[DICE_TYPE], 
				 pMobIndex->hit[DICE_BONUS]);
	fprintf(fp, "%dd%d+%d ", pMobIndex->mana[DICE_NUMBER],
			 	 pMobIndex->mana[DICE_TYPE], 
				 pMobIndex->mana[DICE_BONUS]);
	fprintf(fp, "%dd%d+%d ", pMobIndex->damage[DICE_NUMBER],
			         pMobIndex->damage[DICE_TYPE], 
				 pMobIndex->damage[DICE_BONUS]);
	fprintf(fp, "%s\n", attack_table[pMobIndex->dam_type].name);
	fprintf(fp, "%d %d %d %d\n", 	pMobIndex->ac[AC_PIERCE] / 10,
			 		pMobIndex->ac[AC_BASH] / 10, 
					pMobIndex->ac[AC_SLASH] / 10,
			 		pMobIndex->ac[AC_EXOTIC] / 10);
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->off_flags, buf));
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->imm_flags, buf));
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->res_flags, buf));
	fprintf(fp, "%s\n", fwrite_flags(pMobIndex->vuln_flags, buf));
    	fprintf( fp, "%s %s %s %ld\n",	position_table[pMobIndex->start_pos].short_name,
					position_table[pMobIndex->default_pos].short_name,
					sex_table[pMobIndex->sex].name,
					pMobIndex->wealth );
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->form, buf));
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->parts, buf));
	fprintf(fp, "%s ", size_table[pMobIndex->size].name);
	fprintf(fp, "'%s'\n", IS_NULLSTR(pMobIndex->material)? "unknown":pMobIndex->material);

    	for ( pMprog = pMobIndex->mprogs; pMprog; pMprog = pMprog->next )
    	{
        	fprintf ( fp, "M %s %d %s~\n",
                  	mprog_type_to_name ( pMprog->trig_type ), pMprog->prog->vnum,
                  	pMprog->trig_phrase );
    	}
	return;
}
/**************************************************************************/
void savesd_mobile(FILE *fp, MOB_INDEX_DATA *pMobIndex)
{
    	sh_int race = pMobIndex->race;
    	MPROG_LIST *pMprog;
	int align = 0;
	char buf[MSL];

	fprintf(fp, "#%d\n", pMobIndex->vnum);
	fprintf(fp, "%s~\n", pMobIndex->player_name);
	fprintf(fp, "%s~\n", pMobIndex->short_descr);
	fprintf(fp, "%s\n~\n", fix_string(pMobIndex->long_descr));
	fprintf(fp, "%s~\n", fix_string(pMobIndex->description));
	fprintf(fp, "%s~\n", race_table[race]->name);
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->act, buf));
	fprintf(fp, "0 "); /* affected by 2 */
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->affected_by, buf));
	fprintf(fp, "0 "); /* shielded by */
    	switch(pMobIndex->alliance)
    	{
		case 3:
			align = 600;
			break;
		case 2:
			align = 400;
			break;
		case 1:
			align = 200;
			break;
		case 0:
			align = 0;
			break;
		case -1:
			align = -200;
			break;
		case -2:
			align = -400;
			break;
		case -3:
			align = -600;
			break;
	}
	fprintf(fp, "%d 0\n", align);
	fprintf(fp, "%d %d ", pMobIndex->level, pMobIndex->hitroll);
	fprintf(fp, "%dd%d+%d ", pMobIndex->hit[DICE_NUMBER],
			         pMobIndex->hit[DICE_TYPE], 
				 pMobIndex->hit[DICE_BONUS]);
	fprintf(fp, "%dd%d+%d ", pMobIndex->mana[DICE_NUMBER],
			 	 pMobIndex->mana[DICE_TYPE], 
				 pMobIndex->mana[DICE_BONUS]);
	fprintf(fp, "%dd%d+%d ", pMobIndex->damage[DICE_NUMBER],
			         pMobIndex->damage[DICE_TYPE], 
				 pMobIndex->damage[DICE_BONUS]);
	fprintf(fp, "%s\n", attack_table[pMobIndex->dam_type].name);
	fprintf(fp, "%d %d %d %d\n", 	pMobIndex->ac[AC_PIERCE] / 10,
			 		pMobIndex->ac[AC_BASH] / 10, 
					pMobIndex->ac[AC_SLASH] / 10,
			 		pMobIndex->ac[AC_EXOTIC] / 10);
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->off_flags, buf));
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->imm_flags, buf));
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->res_flags, buf));
	fprintf(fp, "%s\n", fwrite_flags(pMobIndex->vuln_flags, buf));
    	fprintf( fp, "%s %s %s %ld\n",	position_table[pMobIndex->start_pos].short_name,
					position_table[pMobIndex->default_pos].short_name,
					sex_table[pMobIndex->sex].name,
					pMobIndex->wealth );
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->form, buf));
	fprintf(fp, "%s ", fwrite_flags(pMobIndex->parts, buf));
	fprintf(fp, "%s ", size_table[pMobIndex->size].name);
	fprintf(fp, "'%s'\n", IS_NULLSTR(pMobIndex->material)? "unknown":pMobIndex->material);

    	for ( pMprog = pMobIndex->mprogs; pMprog; pMprog = pMprog->next )
    	{
        	fprintf ( fp, "M %s %d %s~\n",
                  	mprog_type_to_name ( pMprog->trig_type ), pMprog->prog->vnum,
                  	pMprog->trig_phrase );
    	}
	return;
}
/**************************************************************************/
void saverom_mobiles(FILE * fp, AREA_DATA * pArea)
{
    	int i;
    	MOB_INDEX_DATA *pMob;

    	fprintf( fp, "#MOBILES\n" );

	for (i = pArea->min_vnum; i <= pArea->max_vnum; i++)
	{
		if ((pMob = get_mob_index(i)))
			saverom_mobile(fp, pMob);
	}

    	fprintf( fp, "#0\n\n\n\n" );
	return;
}
/**************************************************************************/
void savesd_mobiles(FILE * fp, AREA_DATA * pArea)
{
    	int i;
    	MOB_INDEX_DATA *pMob;

    	fprintf( fp, "#MOBILES\n" );

	for (i = pArea->min_vnum; i <= pArea->max_vnum; i++)
	{
		if ((pMob = get_mob_index(i)))
			savesd_mobile(fp, pMob);
	}

    	fprintf( fp, "#0\n\n\n\n" );
	return;
}
/**************************************************************************/
void saverom_object ( FILE * fp, OBJ_INDEX_DATA * pObjIndex )
{
    char letter;
    AFFECT_DATA *pAf;
    EXTRA_DESCR_DATA *pEd;
    char buf[MSL];

    fprintf ( fp, "#%d\n", pObjIndex->vnum );
    fprintf ( fp, "%s~\n", pObjIndex->name );
    fprintf ( fp, "%s~\n", pObjIndex->short_descr );
    fprintf ( fp, "%s~\n", fix_string ( pObjIndex->description ) );
    fprintf ( fp, "'%s'~\n", pObjIndex->material );
    fprintf ( fp, "%s ", item_name ( pObjIndex->item_type ) );
    fprintf ( fp, "%s ", fwrite_flags ( pObjIndex->extra_flags, buf ) );
    fprintf ( fp, "%s\n", fwrite_flags ( pObjIndex->wear_flags, buf ) );

    switch ( pObjIndex->item_type )
    {
        default:
            fprintf ( fp, "%s ", fwrite_flags( pObjIndex->value[0], buf));
            fprintf ( fp, "%s ", fwrite_flags( pObjIndex->value[1], buf));
            fprintf ( fp, "%s ", fwrite_flags( pObjIndex->value[2], buf));
            fprintf ( fp, "%s ", fwrite_flags( pObjIndex->value[3], buf));
            fprintf ( fp, "%s\n", fwrite_flags( pObjIndex->value[4], buf));
            break;

        case ITEM_LIGHT:
            fprintf ( fp, "0 0 %d 0 0\n", pObjIndex->value[2] < 1 ? 999    /* infinite */
                      : pObjIndex->value[2] );
            break;

        case ITEM_MONEY:
            fprintf ( fp, "%d %d 0 0 0\n", pObjIndex->value[0],
                      pObjIndex->value[1] );
            break;

        case ITEM_DRINK_CON:
            fprintf ( fp, "%d %d '%s' %d 0\n", pObjIndex->value[0],
                      pObjIndex->value[1],
                      liq_table[pObjIndex->value[2]].liq_name,
                      pObjIndex->value[3] );
            break;

        case ITEM_FOUNTAIN:
            fprintf ( fp, "%d %d '%s' 0 0\n", pObjIndex->value[0],
                      pObjIndex->value[1],
                      liq_table[pObjIndex->value[2]].liq_name );
            break;

        case ITEM_CONTAINER:
            fprintf ( fp, "%d %s %d %d %d\n", pObjIndex->value[0],
                      fwrite_flags( pObjIndex->value[1], buf),
                      pObjIndex->value[2], pObjIndex->value[3],
                      pObjIndex->value[4] );
            break;

        case ITEM_FOOD:
            fprintf ( fp, "%d %d 0 %s 0\n", pObjIndex->value[0],
                      pObjIndex->value[1], fwrite_flags ( pObjIndex->value[3], buf) );
            break;

        case ITEM_PORTAL:
            fprintf ( fp, "%d %s %s %d 0\n", pObjIndex->value[0],
                      fwrite_flags ( pObjIndex->value[1], buf),
                      fwrite_flags ( pObjIndex->value[2], buf),
                      pObjIndex->value[3] );
            break;

        case ITEM_FURNITURE:
            fprintf ( fp, "%d %d %s %d %d\n", pObjIndex->value[0],
                      pObjIndex->value[1], fwrite_flags ( pObjIndex->value[2], buf),
                      pObjIndex->value[3], pObjIndex->value[4] );
            break;

        case ITEM_WEAPON:
            fprintf ( fp, "%s %d %d %s %s\n",
                      weapon_name ( pObjIndex->value[0] ),
                      pObjIndex->value[1], pObjIndex->value[2],
                      attack_table[pObjIndex->value[3]].name,
                      fwrite_flags ( pObjIndex->value[4], buf ) );
            break;

        case ITEM_ARMOR:
            fprintf ( fp, "%d %d %d %d %d\n", pObjIndex->value[0],
                      pObjIndex->value[1], pObjIndex->value[2],
                      pObjIndex->value[3], pObjIndex->value[4] );
            break;

        case ITEM_PILL:
        case ITEM_POTION:
        case ITEM_SCROLL:
            fprintf ( fp, "%d '%s' '%s' '%s' '%s'\n", pObjIndex->value[0] > 0 ?    /* no negative numbers */
                      pObjIndex->value[0] : 0,
                      pObjIndex->value[1] !=
                      -1 ? skill_table[pObjIndex->value[1]].name : "",
                      pObjIndex->value[2] !=
                      -1 ? skill_table[pObjIndex->value[2]].name : "",
                      pObjIndex->value[3] !=
                      -1 ? skill_table[pObjIndex->value[3]].name : "",
                      pObjIndex->value[4] !=
                      -1 ? skill_table[pObjIndex->value[4]].name : "" );
            break;

        case ITEM_STAFF:
        case ITEM_WAND:
            fprintf ( fp, "%d ", pObjIndex->value[0] );
            fprintf ( fp, "%d ", pObjIndex->value[1] );
            fprintf ( fp, "%d '%s' 0\n", pObjIndex->value[2],
                      pObjIndex->value[3] !=
                      -1 ? skill_table[pObjIndex->value[3]].name : 0 );
            break;
    }

    fprintf ( fp, "%d ", pObjIndex->level );
    fprintf ( fp, "%d ", pObjIndex->weight );
    fprintf ( fp, "%d ", pObjIndex->cost );

    if ( pObjIndex->condition > 90 )
        letter = 'P';
    else if ( pObjIndex->condition > 75 )
        letter = 'G';
    else if ( pObjIndex->condition > 50 )
        letter = 'A';
    else if ( pObjIndex->condition > 25 )
        letter = 'W';
    else if ( pObjIndex->condition > 10 )
        letter = 'D';
    else if ( pObjIndex->condition > 0 )
        letter = 'B';
    else
        letter = 'R';

    fprintf ( fp, "%c\n", letter );

    for ( pAf = pObjIndex->affected; pAf; pAf = pAf->next )
    {
        if ( pAf->where == WHERE_OBJEXTRA || pAf->bitvector == 0 )
            fprintf ( fp, "A\n%d %d\n", pAf->location, pAf->modifier );
        else
        {
            fprintf ( fp, "F\n" );

            switch ( pAf->where )
            {
                case WHERE_AFFECTS:
                    fprintf ( fp, "A " );
                    break;
                case WHERE_IMMUNE:
                    fprintf ( fp, "I " );
                    break;
                case WHERE_RESIST:
                    fprintf ( fp, "R " );
                    break;
                case WHERE_VULN:
                    fprintf ( fp, "V " );
                    break;
                default:
                    bug("olc_save: Invalid Affect->where");
                    break;
            }

            fprintf ( fp, "%d %d %s\n", pAf->location, pAf->modifier,
                      fwrite_flags( pAf->bitvector, buf ) );
        }
    }

    for( pEd = pObjIndex->extra_descr; pEd; pEd = pEd->next )
    {
        if (is_space(pEd->description[0]))
        {
            fprintf( fp, "E\n%s~\n.%s~\n", pEd->keyword,
             fix_string( pEd->description ) );
        }
        else
        {   
            fprintf( fp, "E\n%s~\n%s~\n", pEd->keyword,
             fix_string( pEd->description ) );
        }
    }

    return;
}
/**************************************************************************/
void saverom_objects ( FILE * fp, AREA_DATA * pArea )
{
    int i;
    OBJ_INDEX_DATA *pObj;

    fprintf ( fp, "#OBJECTS\n" );

    for ( i = pArea->min_vnum; i <= pArea->max_vnum; i++ )
    {
        if ( ( pObj = get_obj_index ( i ) ) )
            saverom_object ( fp, pObj );
    }

    fprintf ( fp, "#0\n\n\n\n" );
    return;
}
/**************************************************************************/
void saverom_rooms ( FILE * fp, AREA_DATA * pArea )
{
    ROOM_INDEX_DATA *pRoomIndex;
    EXTRA_DESCR_DATA *pEd;
    EXIT_DATA *pExit;
    int iHash;
    int door;
    char buf[MSL];

    fprintf ( fp, "#ROOMS\n" );
    for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
    {
        for ( pRoomIndex = room_index_hash[iHash]; pRoomIndex;
              pRoomIndex = pRoomIndex->next )
        {
            if ( pRoomIndex->area == pArea )
            {
                fprintf ( fp, "#%d\n", pRoomIndex->vnum );
                fprintf ( fp, "%s~\n", pRoomIndex->name );
                fprintf ( fp, "%s~\n", 
				fix_string (pRoomIndex->description ) );
		fprintf ( fp, "0 %s %d\n", 
				fwrite_flags(pRoomIndex->room_flags, buf),
				pRoomIndex->sector_type);

                for ( pEd = pRoomIndex->extra_descr; pEd; pEd = pEd->next )
                {
                    fprintf ( fp, "E\n%s~\n%s~\n", pEd->keyword, fix_string ( pEd->description ) );
                }
                for ( door = 0; door < MAX_DIR; door++ )    /* I hate this! */
                {
                    if ( ( pExit = pRoomIndex->exit[door] ) &&
                         pExit->u1.to_room )
                    {
                        int locks = 0;
                        if ( IS_SET ( pExit->rs_flags, EX_ISDOOR ) &&
                             ( !IS_SET ( pExit->rs_flags, EX_PICKPROOF ) ) &&
                             ( !IS_SET ( pExit->rs_flags, EX_NOPASS ) ) )
                            locks = 1;
                        if ( IS_SET ( pExit->rs_flags, EX_ISDOOR ) &&
                             ( IS_SET ( pExit->rs_flags, EX_PICKPROOF ) ) &&
                             ( !IS_SET ( pExit->rs_flags, EX_NOPASS ) ) )
                            locks = 2;
                        if ( IS_SET ( pExit->rs_flags, EX_ISDOOR ) &&
                             ( !IS_SET ( pExit->rs_flags, EX_PICKPROOF ) ) &&
                             ( IS_SET ( pExit->rs_flags, EX_NOPASS ) ) )
                            locks = 3;
                        if ( IS_SET ( pExit->rs_flags, EX_ISDOOR ) &&
                             ( IS_SET ( pExit->rs_flags, EX_PICKPROOF ) ) &&
                             ( IS_SET ( pExit->rs_flags, EX_NOPASS ) ) )
                            locks = 4;

                        fprintf ( fp, "D%d\n", door );
                        fprintf ( fp, "%s~\n",
                                  fix_string ( pExit->description ) );
                        fprintf ( fp, "%s~\n", pExit->keyword );
                        fprintf ( fp, "%d %d %d\n", locks, pExit->key,
                                  pExit->u1.to_room->vnum );
                    }
                }
                if ( pRoomIndex->mana_rate != 100 ||
                     pRoomIndex->heal_rate != 100 )
                    fprintf ( fp, "M %d H %d\n", pRoomIndex->mana_rate,
                              pRoomIndex->heal_rate );

                if ( pRoomIndex->owner && str_cmp ( pRoomIndex->owner, "" ) )
                    fprintf ( fp, "O %s~\n", pRoomIndex->owner );

                fprintf ( fp, "S\n" );
            }
        }
    }
    fprintf ( fp, "#0\n\n\n\n" );
    return;
}
/**************************************************************************/
void saverom_specials ( FILE * fp, AREA_DATA * pArea )
{
    int iHash;
    MOB_INDEX_DATA *pMobIndex;

    fprintf ( fp, "#SPECIALS\n" );

    for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
    {
        for ( pMobIndex = mob_index_hash[iHash]; pMobIndex;
              pMobIndex = pMobIndex->next )
        {
            if ( pMobIndex && pMobIndex->area == pArea &&
                 pMobIndex->spec_fun )
            {
                fprintf ( fp, "M %d %s\n", pMobIndex->vnum,
                          spec_name ( pMobIndex->spec_fun ) );
            }
        }
    }

    fprintf ( fp, "S\n\n\n\n" );
    return;
}
/**************************************************************************/
void save_door_resets ( FILE * fp, AREA_DATA * pArea )
{
    int iHash;
    ROOM_INDEX_DATA *pRoomIndex;
    EXIT_DATA *pExit;
    int door;

    for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
    {
        for ( pRoomIndex = room_index_hash[iHash]; pRoomIndex;
              pRoomIndex = pRoomIndex->next )
        {
            if ( pRoomIndex->area == pArea )
            {
                for ( door = 0; door < MAX_DIR; door++ )
                {
                    if ( ( pExit = pRoomIndex->exit[door] ) &&
                         pExit->u1.to_room &&
                         ( IS_SET ( pExit->rs_flags, EX_CLOSED ) ||
                           IS_SET ( pExit->rs_flags, EX_LOCKED ) ) )

                    fprintf ( fp, "D 0 %d %d %d\n", pRoomIndex->vnum,
                              door, IS_SET ( pExit->rs_flags,
                                                         EX_LOCKED ) ? 2 :
                              1 );
                }
            }
        }
    }
    return;
}
/**************************************************************************/
void saverom_resets ( FILE * fp, AREA_DATA * pArea )
{
    RESET_DATA *pReset;
    MOB_INDEX_DATA *pLastMob = NULL;
    OBJ_INDEX_DATA *pLastObj;
    ROOM_INDEX_DATA *pRoom;
    char buf[MSL];
    int iHash;

    fprintf ( fp, "#RESETS\n" );

    save_door_resets ( fp, pArea );

    for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
    {
        for ( pRoom = room_index_hash[iHash]; pRoom; pRoom = pRoom->next )
        {
            if ( pRoom->area == pArea )
            {
                for ( pReset = pRoom->reset_first; pReset;
                      pReset = pReset->next )
                {
                    switch ( pReset->command )
                    {
                        default:
                            bug ( "Save_resets: bad command." );
                            break;
                        case 'M':
                            pLastMob = get_mob_index ( pReset->arg1 );
                            fprintf ( fp, "M 0 %d %d %d %d\n", pReset->arg1,
                                      pReset->arg2, pReset->arg3,
                                      pReset->arg4 );
                            break;

                        case 'O':
                            pLastObj = get_obj_index ( pReset->arg1 );
                            pRoom = get_room_index ( pReset->arg3 );
                            fprintf ( fp, "O 0 %d 0 %d\n", pReset->arg1,
                                      pReset->arg3 );
                            break;

                        case 'P':
                            pLastObj = get_obj_index ( pReset->arg1 );
                            fprintf ( fp, "P 0 %d %d %d %d\n", pReset->arg1,
                                      pReset->arg2, pReset->arg3,
                                      pReset->arg4 );
                            break;

                        case 'G':
                            fprintf ( fp, "G 0 %d 0\n", pReset->arg1 );
                            if ( !pLastMob )
                            {
                                sprintf ( buf,
                                          "Save_resets: !NO_MOB! in [%s]",
                                          pArea->file_name );
                                bug ( buf );
                            }
                            break;

                        case 'E':
                            fprintf ( fp, "E 0 %d 0 %d\n", pReset->arg1,
                                      pReset->arg3 );
                            if ( !pLastMob )
                            {
                                sprintf ( buf,
                                          "Save_resets: !NO_MOB! in [%s]",
                                          pArea->file_name );
                                bug ( buf );
                            }
                            break;

                        case 'D':
                            break;

                        case 'R':
                            pRoom = get_room_index ( pReset->arg1 );
                            fprintf ( fp, "R 0 %d %d\n", pReset->arg1,
                                      pReset->arg2 );
                            break;
                    }
                }
            }                   /* End if correct area */
        }                       /* End for pRoom */
    }                           /* End for iHash */

    fprintf ( fp, "S\n\n\n\n" );
    return;
}
/**************************************************************************/
void saverom_shops ( FILE * fp, AREA_DATA * pArea )
{
    SHOP_DATA *pShopIndex;
    MOB_INDEX_DATA *pMobIndex;
    int iTrade;
    int iHash;

    fprintf ( fp, "#SHOPS\n" );

    for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
    {
        for ( pMobIndex = mob_index_hash[iHash]; pMobIndex;
              pMobIndex = pMobIndex->next )
        {
            if ( pMobIndex && pMobIndex->area == pArea && pMobIndex->pShop )
            {
                pShopIndex = pMobIndex->pShop;

                fprintf ( fp, "%d ", pShopIndex->keeper );
                for ( iTrade = 0; iTrade < MAX_TRADE; iTrade++ )
                {
                    if ( pShopIndex->buy_type[iTrade] != 0 )
                    {
                        fprintf ( fp, "%d ", pShopIndex->buy_type[iTrade] );
                    }
                    else
                        fprintf ( fp, "0 " );
                }
                fprintf ( fp, "%d %d ", pShopIndex->profit_buy,
                          pShopIndex->profit_sell );
                fprintf ( fp, "%d %d\n", pShopIndex->open_hour,
                          pShopIndex->close_hour );
            }
        }
    }

    fprintf ( fp, "0\n\n\n\n" );
    return;
}
/**************************************************************************/
void saverom_area ( AREA_DATA * pArea )
{
    FILE *fp=NULL;
    char write_filename[MIL];

    sprintf(write_filename, "%s.ROM", pArea->file_name);

    if ( !( fp = fopen ( write_filename, "w" ) ) )
    {
        bug ( "Open_area: fopen" );
        perror ( pArea->file_name );
    }

    fprintf ( fp, "#AREADATA\n" );
    fprintf ( fp, "Name %s~\n", pArea->name );
    fprintf ( fp, "Builders %s~\n", fix_string ( pArea->builders ) );
    fprintf ( fp, "VNUMs %d %d\n", pArea->min_vnum, pArea->max_vnum );
    fprintf ( fp, "Credits %s~\n", pArea->credits );
    fprintf ( fp, "Security %d\n", pArea->security );
    fprintf ( fp, "End\n\n\n\n" );

    saverom_mobiles ( fp, pArea );
//    savesd_mobiles ( fp, pArea );
    saverom_objects ( fp, pArea );
    saverom_rooms ( fp, pArea );
    saverom_specials ( fp, pArea );
    saverom_resets ( fp, pArea );
    saverom_shops ( fp, pArea );
    saverom_mobprogs ( fp, pArea );

    fprintf ( fp, "#$\n" );

    fclose ( fp );
    return;
}
/**************************************************************************/
void do_romexport( char_data *ch, char *argument )
{
    	AREA_DATA *pArea;
	ch->printlnf("Saving the world into ROM format....");
	for( pArea = area_first; pArea; pArea = pArea->next )
	{
		ch->printlnf("Saving %s.ROM", pArea->file_name);
		saverom_area( pArea );
	}
	ch->printlnf("ROM EXPORT COMPLETE.");
	return;
}
/**************************************************************************/
/**************************************************************************/