/*~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
~ 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. ~
~ ~
~ Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley ~
~ ACK!MUD is modified Merc2.0/2.1/2.2 code (c)Stephen Zepp 1998 Ver: 4.3 ~
~ ~
~ In order to use any part of this PA Diku Mud, you must comply with ~
~ both the original Diku license in 'license.doc' as well the Merc ~
~ license in 'license.txt', and the Ack!Mud license in 'ack_license.txt'.~
~ In particular, you may not remove any of these copyright notices. ~
~ ~
~ _______ _____ ~
~ / __ /\ / ___ \ 222222 PA_MUD by Amnon Kruvi ~
~ /______/ / / /___\ \ 2 PA_MUD is modified ~
~ / _______/ / _______ \ 2 Ack!Mud, v4.3 ~
~ /_/ /_/ \_\ 2 ~
~ 2 ~
~ 2222222 ~
~ ~
~ ~
~ Years of work have been invested to create DIKU, Merc, Ack and PA. ~
~ Please show your respect by following the licenses, and issuing ~
~ credits where due. ~
~ ~
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-*/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ack.h"
/* Way this works:
Mud reads in area files, stores details in data lists.
Edit rooms, objects, resets.
type savearea.
Sets bool saving_area to true.
Incrementally saves an area, using data lists.
*/
#define SAVEQUEUESIZE 50
#define NOT_SAVING 0
#define START_SAVING 1
#define AM_SAVING 2
#define BUILD_OK -1
#define BUILD_CANTSAVE 1
#define BUILD_TOOMANY 2
#define BUILD_SEC_AREA 1
#define BUILD_SEC_HELP 2
#define BUILD_SEC_ROOMS 3
#define BUILD_SEC_OBJECTS 4
#define BUILD_SEC_END 5
#define AREA_VERSION 20
struct save_queue_type
{
AREA_DATA * area;
CHAR_DATA * ch;
int loops;
} SaveQ[SAVEQUEUESIZE];
/* Semi-local vars. */
int saving_area=0;
/* local */
int offset;
int ToBeSaved=0;
int CurrentSaving=-1;
AREA_DATA * CurSaveArea=NULL;
CHAR_DATA * CurSaveChar=NULL;
int CurLoops=1;
int Section;
BUILD_DATA_LIST * Pointer;
FILE * SaveFile;
FILE * Envy;
int AreasModified=0;
/* Local functions */
/* void build_save(); proto in merc.h */
void build_save_area(void);
void build_save_help(void);
void build_save_mobs(void);
void build_save_mobprogs(void);
void build_save_objects(void);
void build_save_rooms(void);
void build_save_resets(void);
void build_save_objfuns(void);
void build_save_end(void);
char * mprog_type_to_name(int);
void vuild_save_flush(void);
/* int convert(int lev); */
/* Convert levels from ack -> envy! */
/* int convert(int lev) */
/* { */
/* return( lev - ( lev/5 ) ); */
/* } */
void do_savearea( CHAR_DATA *ch, char *argument )
{
AREA_DATA * SaveArea;
int loops;
/* char first_arg[MAX_INPUT_LENGTH]; unused? */
if (ch==NULL)
{
SaveArea=(AREA_DATA *) argument;
loops=10;
}
else
{
if (ch->in_room==NULL)
{
send_to_char("Do not know what room you are in!!, cannot save.\n",ch);
return;
}
SaveArea=(ch->in_room)->area;
if (SaveArea==NULL)
{
send_to_char("Do not know what area you are in!!, cannot save.\n",ch);
return;
}
if (*argument != '\0')
{
loops=atoi(argument);
if (loops<1)
loops=1;
}
else
loops=1;
}
if (ToBeSaved==CurrentSaving)
{
send_to_char("Too many areas in queue, please try later.\n",ch);
return;
}
SaveQ[ToBeSaved].area=SaveArea;
SaveQ[ToBeSaved].ch=ch;
SaveQ[ToBeSaved].loops=loops;
ToBeSaved=(ToBeSaved + 1) % SAVEQUEUESIZE;
if (saving_area==NOT_SAVING)
saving_area=START_SAVING;
else
send_to_char("Save is queued, please wait. \n",ch);
build_save();
return;
}
void build_save()
{
int a;
char filename[255];
char buf[MAX_STRING_LENGTH];
for (a=0;a<CurLoops && saving_area>0;a++)
{
if ( saving_area== START_SAVING)
{
CurrentSaving=(CurrentSaving+1) % SAVEQUEUESIZE;
CurSaveArea=SaveQ[CurrentSaving].area;
CurSaveChar=SaveQ[CurrentSaving].ch;
CurLoops=SaveQ[CurrentSaving].loops;
send_to_char("Starting Save.\n",CurSaveChar);
sprintf(filename,"%s.new",CurSaveArea->filename);
SaveFile=fopen(filename,"w");
if (SaveFile==NULL)
{
if (CurrentSaving==ToBeSaved)
saving_area=NOT_SAVING;
send_to_char("Can not open file for saving.\n",CurSaveChar);
return;
}
/* Open second file for saving in envy format */
sprintf( buf, "Starting to save %s", CurSaveArea->filename );
monitor_chan( NULL, buf, MONITOR_AREA_SAVING );
Section=1;
offset=CurSaveArea->offset;
saving_area=AM_SAVING;
Pointer=NULL;
}
switch (Section)
{
case BUILD_SEC_AREA: build_save_area(); break;
case BUILD_SEC_HELP: build_save_help(); break;
case BUILD_SEC_ROOMS: build_save_rooms(); break;
case BUILD_SEC_OBJECTS: build_save_objects(); break;
case BUILD_SEC_END: build_save_end(); break;
}
}
return;
}
void build_save_area()
{
fprintf(SaveFile,"#AREA\n");
fprintf(SaveFile,"%s~\n",CurSaveArea->name);
fprintf( SaveFile,"Q %i\n", AREA_VERSION );
fprintf(SaveFile,"K %s~\n",CurSaveArea->keyword);
fprintf(SaveFile,"N %i\n",CurSaveArea->area_num);
fprintf(SaveFile,"V %i %i\n",CurSaveArea->min_vnum,CurSaveArea->max_vnum);
fprintf(SaveFile,"X %i\n", CurSaveArea->offset );
if (CurSaveArea->owner != NULL)
fprintf(SaveFile,"O %s~\n",CurSaveArea->owner);
if (CurSaveArea->can_read != NULL)
fprintf(SaveFile,"R %s~\n",CurSaveArea->can_read);
if (CurSaveArea->can_write != NULL)
fprintf(SaveFile,"W %s~\n",CurSaveArea->can_write);
/* fprintf( Envy, "#AREA\n" ); remove save bug */
/* fprintf( Envy, "%s~\n", CurSaveArea->name ); */
Section++;
}
void build_save_help()
{
HELP_DATA *pHelp;
if (Pointer==NULL) /* Start */
{
if (CurSaveArea->first_area_help_text==NULL)
{
Section++;
return;
}
send_to_char("Saving help section.\n",CurSaveChar);
fprintf(SaveFile,"#HELPS\n");
Pointer=CurSaveArea->first_area_help_text;
}
pHelp=Pointer->data;
fprintf(SaveFile,"%i %s~\n",pHelp->level,pHelp->keyword);
if (isspace(pHelp->text[0]))
fprintf(SaveFile,".%s~\n",pHelp->text);
else
fprintf(SaveFile,"%s~\n",pHelp->text);
Pointer=Pointer->next;
if (Pointer==NULL) /* End */
{
fprintf(SaveFile,"0 $~\n");
Section++;
}
/* No saving helps for envy format */
return;
}
void build_save_objects()
{
OBJ_INDEX_DATA *pObject;
// int val0,val1,val2,val3;
int i;
if (Pointer==NULL) /* Start */
{
if (CurSaveArea->first_area_object==NULL)
{
Section++;
return;
}
send_to_char("Saving objects.\n",CurSaveChar);
fprintf(SaveFile,"#OBJECTS\n");
Pointer=CurSaveArea->first_area_object;
}
pObject=Pointer->data;
fprintf(SaveFile,"#%i\n",pObject->vnum);
fprintf(SaveFile,"%s~\n",pObject->name);
fprintf(SaveFile,"%s~\n",pObject->short_descr);
fprintf(SaveFile,"%s~\n",pObject->description);
fprintf(SaveFile,"%i %i %i\n",pObject->item_type,pObject->extra_flags,
pObject->wear_flags);
for ( i=0;i<MAX_OBJECT_VALUES;i++ )
fprintf(SaveFile,"%i ", pObject->value[i]);
/* fprintf(SaveFile,"%i %i %i %i %i %i %i %i %i %i\n",val0,val1,val2,val3,
pObject->value[4], pObject->value[5],pObject->value[6],pObject->value[7],
pObject->value[8],pObject->value[9]); */
fprintf(SaveFile,"%i %i %i %ld\n",pObject->weight,pObject->heat,pObject->building,pObject->cost);
fprintf(SaveFile,"%s~\n",pObject->image);
if ( ( pObject->level > 1 ) && (pObject->level < 130 ) )
{
fprintf(SaveFile, "L\n");
fprintf(SaveFile,"%d\n",pObject->level);
}
else
{
fprintf(SaveFile, "L\n");
fprintf(SaveFile,"%d\n", 1);
}
/* Now for Envy... taken from my OLC :P */
Pointer=Pointer->next;
if (Pointer==NULL) /* End */
{
fprintf(SaveFile,"#0\n");
Section++;
}
return;
}
void build_save_rooms()
{
ROOM_INDEX_DATA *pRoomIndex;
if (Pointer==NULL) /* Start */
{
if (CurSaveArea->first_area_room==NULL)
{
Section++;
return;
}
send_to_char("Saving rooms.\n",CurSaveChar);
fprintf(SaveFile,"#ROOMS\n");
Pointer=CurSaveArea->first_area_room;
}
pRoomIndex=Pointer->data;
fprintf(SaveFile,"#%i\n",pRoomIndex->vnum);
/* End of one room */
fprintf(SaveFile,"S\n");
Pointer=Pointer->next;
if (Pointer==NULL) /* End */
{
fprintf(SaveFile,"#0\n");
Section++;
}
return;
}
void build_save_end()
{
char filename[255];
char buf[MAX_STRING_LENGTH];
sprintf( buf, "Finished saving %s", CurSaveArea->filename );
monitor_chan( NULL, buf, MONITOR_AREA_SAVING );
fprintf(SaveFile,"#$\n");
send_to_char("Finished saving.\n",CurSaveChar);
fclose(SaveFile);
/* Save backup */
sprintf(filename,"%s.old",CurSaveArea->filename);
rename(CurSaveArea->filename,filename);
/* And rename .new to area filename */
sprintf(filename,"%s.new",CurSaveArea->filename);
rename(filename,CurSaveArea->filename);
Section=0;
if (ToBeSaved==(CurrentSaving+1) % SAVEQUEUESIZE)
saving_area=NOT_SAVING;
else
saving_area=START_SAVING;
}
void build_save_flush()
{
AREA_DATA * pArea;
if (AreasModified == 0)
return;
for (pArea=first_area; pArea != NULL; pArea=pArea->next)
{
if (pArea->modified)
{
pArea->modified=0;
do_savearea(NULL,(char *) pArea);
}
}
AreasModified=0;
}
void area_modified(AREA_DATA * pArea)
{
pArea->modified=1;
AreasModified=1;
}