/*___________________________________________________________________________*
)()( 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;
}