/*___________________________________________________________________________* )()( DalekenMUD 1.12 (C) 2000 )()( `][' by Martin Thomson, Lee Brooks, `][' || Ken Herbert and David Jacques || || ----------------------------------------------------------------- || || Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, || || David Love, Guilherme 'Willie' Arnold, and Mitchell Tse. || || Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael || || Chastain, Michael Quan, and Mitchell Tse. || || Original Diku Mud copyright (C) 1990, 1991 || || by Sebastian Hammer, Michael Seifert, Hans Henrik St{rfeldt, || || Tom Madsen, and Katja Nyboe. || || ----------------------------------------------------------------- || || Any use of this software must follow the licenses of the || || creators. Much time and thought has gone into this software and || || you are benefitting. We hope that you share your changes too. || || What goes around, comes around. || || ----------------------------------------------------------------- || || olc_save.c || || Saving routines for areas. || *_/<>\_________________________________________________________________/<>\_*/ #include "mud.h" #include "olc.h" #include "db.h" /* * Local functions. */ void save_area_list args( ( void ) ); /***************************************************************************** Name: fix_string Purpose: Returns a string without \r and ~. ****************************************************************************/ char *fix_string( char *strfix, const char *str ) { int i; int o; if( str == NULL || str[0] == '\0' || strlen( str ) > MAX_STRING_LENGTH ) return strcpy( strfix, "" ); for( o = i = 0; str[i + o] != '\0'; i++ ) { while( str[i + o] == '\r' || str[i + o] == '~' ) o++; strfix[i] = str[i + o]; } strfix[i] = '\0'; return strfix; } /***************************************************************************** Name: save_area_list Purpose: Saves the listing of files to be loaded at startup. Called by: do_asave (olc_save.c). ****************************************************************************/ void save_area_list( ) { FILE *fp; AREA_DATA *pArea; if( ( fp = open_file( AREA_DIR AREA_LIST, "w", FALSE ) ) == NULL ) { bug( "Save_area_list: open_file" ); perror( AREA_DIR AREA_LIST ); } else { /* * Add any help files that need to be loaded at * startup to this section. * These are the files which don't have a '@AREA' section. * fprintf( fp, "all.hlp\n" ); */ for( pArea = area_first; pArea; pArea = pArea->next ) { if( IS_SET( pArea->area_flags, AREA_DELETED ) ) continue; fprintf( fp, "%s\n", pArea->filename ); } fprintf( fp, "$\n" ); close_file( fp ); } return; } /***************************************************************************** Name: save_mobprogs Purpose: Save the mudprogs used for the entire area. Called by: save_area (olc_save.c). ****************************************************************************/ void save_area_mudprogs( FILE *fp, AREA_DATA *area ) { int i; MPROG_GLOBAL *mprg; for( i = 0; i < MPROG_GLOBAL_HASH; ++i ) for( mprg = global_progs[i]; mprg; mprg = mprg->next ) if( mprg->area == area ) write_next_item( fp, "GProg", mprg ); fprintf( fp, "\n\n" ); return; } /***************************************************************************** Name: save_mobiles Purpose: Save #MOBILES secion of an area file. Called by: save_area( olc_save.c ). ****************************************************************************/ void save_mobiles( FILE *fp, AREA_DATA *pArea ) { int vnum; MOB_INDEX_DATA *pMob; for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ ) { if( ( pMob = get_mob_index( vnum ) ) && pMob->area == pArea ) write_next_item( fp, "Mobile", pMob ); } fprintf( fp, "\n\n" ); return; } /***************************************************************************** Name: save_objects Purpose: Save #OBJECTS section of an area file. Called by: save_area( olc_save.c ). ****************************************************************************/ void save_objects( FILE *fp, AREA_DATA *pArea ) { int vnum; OBJ_INDEX_DATA *pObj; for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ ) { if( ( pObj = get_obj_index( vnum ) ) && pObj->area == pArea ) write_next_item( fp, "Object", pObj ); } fprintf( fp, "\n\n" ); return; } /* OLC 1.1b */ /***************************************************************************** Name: save_rooms Purpose: Save #ROOMDATA section of an area file. Called by: save_area( olc_save.c ). ****************************************************************************/ void save_rooms( FILE *fp, AREA_DATA *pArea ) { ROOM_INDEX_DATA *pRoom; int vnum; for( vnum = pArea->lvnum; vnum <= pArea->uvnum; vnum++ ) { if( ( pRoom = get_room_index( vnum ) ) && pRoom->area == pArea ) write_next_item( fp, "Room", pRoom ); } fprintf( fp, "\n\n" ); return; } /***************************************************************************** Name: save_helps Purpose: Save #HELPS section of an area file. Written by: Walker <nkrendel@evans.Denver.Colorado.EDU> Called by: save_area( olc_save.c ). ****************************************************************************/ void save_helps( FILE * fp, AREA_DATA * pArea ) { HELP_DATA *pHelp; for( pHelp = help_first; pHelp; pHelp = pHelp->next ) { if( pHelp->area != pArea ) continue; write_next_item( fp, "Help", pHelp ); } fprintf( fp, "\n\n" ); return; } /***************************************************************************** Name: save_area Purpose: Save an area, note that this format is new. Called by: do_asave( olc_save.c ). ****************************************************************************/ void save_area( AREA_DATA *pArea ) { FILE *fp; char buf[MAX_INPUT_LENGTH]; if( IS_SET( pArea->area_flags, AREA_DELETED ) || IS_SET( pArea->area_flags, AREA_NOSAVE ) ) return; sprintf( buf, "%s%s", AREA_DIR, pArea->filename ); if( !( fp = open_file( buf, "w", TRUE ) ) ) { bug( "Open_area: open_file" ); perror( buf ); } write_next_item( fp, "Area", pArea ); fprintf( fp, "\n\n" ); save_helps( fp, pArea ); save_area_mudprogs( fp, pArea ); save_mobiles( fp, pArea ); save_objects( fp, pArea ); save_rooms( fp, pArea ); fprintf( fp, "\neof\n\n" ); close_file( fp ); return; } /* OLC 1.1b */ /***************************************************************************** Name: do_asave Purpose: Entry point for saving area data. Called by: interpreter( interp.c ) ****************************************************************************/ void do_asave( CHAR_DATA *ch, const char *argument ) { char arg1[MAX_INPUT_LENGTH]; AREA_DATA *pArea; int value; CHAR_DATA *rch; if( !ch ) /* Do an autosave */ { log_string( "ASave: automatic save of areas." ); send_to_all_char( "&bA gentle breeze comes from the east.&n\n\r" ); /* Turn of the CPU time alarm for this function. */ SET_BIT( SysInfo->flags, SYSINFO_NOCPULIMIT ); save_area_list( ); for( pArea = area_first; pArea; pArea = pArea->next ) { if( IS_SET( SysInfo->flags, SYSINFO_SAVEALL ) || IS_SET( pArea->area_flags, AREA_CHANGED | AREA_ADDED ) ) save_area( pArea ); REMOVE_BIT( pArea->area_flags, AREA_CHANGED | AREA_ADDED ); } REMOVE_BIT( SysInfo->flags, SYSINFO_NOCPULIMIT ); send_to_all_char( "&bAfter the breeze all seems calm.&n\n\r" ); return; } rch = get_char( ch ); if( !authorized( rch, "asave" ) ) return; argument = one_argument( argument, arg1 ); if( arg1[0] == '\0' ) { send_to_char( "Syntax:\n\r" " asave <vnum> - saves a particular area\n\r" " asave list - saves the AREA.LST file\n\r" " asave area - saves the area being edited\n\r" " asave changed - saves all changed zones\n\r" " asave world - saves the world! (db dump)\n\r" " asave ^ verbose - saves in verbose mode\n\r" "\n\r", ch ); return; } /* Snarf the value ( which need not be numeric ). */ value = atoi( arg1 ); /* Save the area of given vnum. */ /* ---------------------------- */ if( !( pArea = get_area_data( value ) ) && is_number( arg1 ) ) { send_to_char( "That area does not exist.\n\r", ch ); return; } if( is_number( arg1 ) ) { if( !IS_BUILDER( ch, pArea ) ) { send_to_char( "You are not a builder for this area.\n\r", ch ); return; } if( IS_SET( pArea->area_flags, AREA_DELETED ) || IS_SET( pArea->area_flags, AREA_DELETED ) ) { send_to_char( "Check the area flags for this area first.\n\r", ch ); send_to_char( "It may be tagged for deletion of be finished.\n\r", ch ); return; } save_area_list( ); if( !str_cmp( "verbose", argument ) ) SET_BIT( pArea->area_flags, AREA_VERBOSE ); save_area( pArea ); REMOVE_BIT( pArea->area_flags, AREA_VERBOSE ); return; } /* Save the world, only authorized areas. */ /* -------------------------------------- */ if( !str_cmp( "world", arg1 ) ) { log_string( "ASave: %s saving the world.", ch->name ); /* Turn of the CPU time alarm for this function. */ SET_BIT( SysInfo->flags, SYSINFO_NOCPULIMIT ); save_area_list( ); for( pArea = area_first; pArea; pArea = pArea->next ) { /* Builder must be assigned this area. */ if( !IS_BUILDER( ch, pArea ) ) continue; if( !str_cmp( "verbose", argument ) ) SET_BIT( pArea->area_flags, AREA_VERBOSE ); save_area( pArea ); REMOVE_BIT( pArea->area_flags, AREA_CHANGED|AREA_ADDED|AREA_VERBOSE ); } REMOVE_BIT( SysInfo->flags, SYSINFO_NOCPULIMIT ); send_to_char( "You saved the world.\n\r", ch ); return; } /* Save changed areas, only authorized areas. */ /* ------------------------------------------ */ if( !str_cmp( "changed", arg1 ) ) { char buf[MAX_INPUT_LENGTH]; /* Turn of the CPU time alarm for this function. */ SET_BIT( SysInfo->flags, SYSINFO_NOCPULIMIT ); save_area_list( ); send_to_char( "Saved zones:\n\r", ch ); sprintf( buf, "None.\n\r" ); for( pArea = area_first; pArea; pArea = pArea->next ) { /* Builder must be assigned this area. */ if( !IS_BUILDER( ch, pArea ) ) continue; /* Save changed areas. */ if( IS_SET( pArea->area_flags, AREA_CHANGED ) || IS_SET( pArea->area_flags, AREA_ADDED ) ) { if( !str_cmp( "verbose", argument ) ) SET_BIT( pArea->area_flags, AREA_VERBOSE ); save_area( pArea ); REMOVE_BIT( pArea->area_flags, AREA_CHANGED | AREA_ADDED | AREA_VERBOSE ); sprintf( buf, "%24s&n - '%s'%s%s\n\r", pArea->name, pArea->filename, IS_SET( pArea->area_flags, AREA_DELETED ) ? " [deleted]" : "", IS_SET( pArea->area_flags, AREA_NOSAVE ) ? " [finished]" : "" ); send_to_char( buf, ch ); } } if( !str_cmp( buf, "None.\n\r" ) ) send_to_char( buf, ch ); REMOVE_BIT( SysInfo->flags, SYSINFO_NOCPULIMIT ); return; } /* Save the AREA.LST file. */ /* ----------------------- */ if( !str_cmp( arg1, "list" ) ) { save_area_list( ); return; } /* Save area being edited, if authorized. */ /* -------------------------------------- */ if( !str_cmp( arg1, "area" ) ) { pArea = get_editing_area( ch ); if( !IS_BUILDER( ch, pArea ) ) { send_to_char( "You are not a builder for this area.\n\r", ch ); return; } if( IS_SET( pArea->area_flags, AREA_DELETED ) || IS_SET( pArea->area_flags, AREA_NOSAVE ) ) { send_to_char( "Check the area flags for this area first.\n\r", ch ); send_to_char( "It may be tagged for deletion or be finished.\n\r", ch ); return; } save_area_list( ); if( !str_cmp( "verbose", argument ) ) SET_BIT( pArea->area_flags, AREA_VERBOSE ); save_area( pArea ); REMOVE_BIT( pArea->area_flags, AREA_CHANGED|AREA_ADDED|AREA_VERBOSE ); send_to_char( "Area saved.\n\r", ch ); return; } /* Show correct syntax. */ /* -------------------- */ do_asave( ch, "" ); return; }