FlCodebase3.1/
FlCodebase3.1/bounty/
FlCodebase3.1/challenge/
FlCodebase3.1/clans/
FlCodebase3.1/gods/
FlCodebase3.1/mobprogs/
FlCodebase3.1/player/
FlCodebase3.1/savemud/
/***************************************************************************
 *  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 Envy Diku Mud, you must comply with   *
 *  the original Diku license in 'license.doc', the Merc license in        *
 *  'license.txt', as well as the Envy license in 'license.nvy'.           *
 *  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-1998 Russ Taylor                         *
 *      ROM has been brought to you by the ROM consortium                  *
 *          Russ Taylor (rtaylor@hypercube.org)                            *
 *          Gabrielle Taylor (gtaylor@hypercube.org)                       *
 *          Brian Moore (zump@rom.org)                                     *
 *      By using this code, you have agreed to follow the terms of the     *
 *      ROM license, in the file Rom24/doc/rom.license                     *
 *                                                                         *
 * Code Adapted and Improved by Abandoned Realms Mud                       *
 * and Aabahran: The Forsaken Lands Mud by Virigoth                        *
 *                                                                         *
 * Continued Production of this code is available at www.flcodebase.com    *
 ***************************************************************************/


#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <malloc.h>
#include "merc.h"
#include "recycle.h"
#include "save_mud.h"
#include "vote.h"
#include "cabal.h"

/***************************************************************/
/*Following is mud status saving routines for Forsaken Lands  */
/*mud created by Virigoth circa 2001.  Copyrighted for Forsaken*/
/*Lands mud Nov 1, 2001.  Do not use or copy without explicit */
/*permission of author. (Voytek Plawny aka Virigoth)	       */
/***************************************************************/



/* sets current mud day/year based on Post-Cataclysm counting where
 * TIME_CATACLYSM is the real life time when cataclysm occured.
 *
 * Should be called ONLY when mud boots up to synchronize time.
 * Hours are NOT synchronize to perserve continous flow of mud time
 * across reboots.
 */
void update_mud_time( long real_time ){
  int buf;

  /* set mud date */
  //we use dummy for hour, in order to keep the hour saved before reboot
  rltom_date(real_time,
	     &buf,
	     &mud_data.time_info.day,
	     &mud_data.time_info.month,
	     &mud_data.time_info.year);

}

  
/* writes the mud data into the save file passed */
bool fwrite_mud( FILE* fp ){
  VOTE_DATA* pv;

/* version first THIS HAS TO BE FIRST*/
  fprintf( fp, "VERSION %d\n", SAVEMUD_VER );

/* lock status */
  if (mud_data.wizlock)
    fprintf( fp, "WIZLOCK\n");
  if (mud_data.newlock)
    fprintf( fp, "NEWLOCK\n");

/* system time data */
  fprintf( fp, "t_crash %d\n", (int) mud_data.crash_time );
  fprintf( fp, "t_save %d\n", (int)  mud_data.save_time );

/* mud time data */
  fprintf( fp, "t_mud %d %d %d %d\n", 
	   mud_data.time_info.hour,
	   mud_data.time_info.day,
	   mud_data.time_info.month,
	   mud_data.time_info.year);

/* mud weather info */
  fprintf( fp, "weather %d %d %d %d\n", 
	   mud_data.weather_info.mmhg,
	   mud_data.weather_info.change,
	   mud_data.weather_info.sky,
	   mud_data.weather_info.sunlight);

/* statistical info */
  fprintf( fp, "max_on %d\n", mud_data.max_on );
  fprintf( fp, "deaths %d\n", mud_data.deaths );
  fprintf( fp, "pfiles %d\n", mud_data.pfiles );
  fprintf( fp, "bounties %d\n", mud_data.bounties );
  fprintf( fp, "sieges %d\n", mud_data.siege_iden );
 
  fprintf( fp, "Questor %s~ %d %ld\n", mud_data.questor, UMAX(1, mud_data.max_quest), mud_data.last_questor );
  
/* votes */
  for (pv = vote_list; pv != NULL; pv = pv->next ){
    fprintf( fp, "Vote\n" );
    write_vote( fp, pv );
  }

/* terminator */
  fprintf( fp, "END\n");
  return TRUE;
}

/* opens the SAVEMUD_FILE for write calls the save functions, */
/* closes it when done					      */
void save_mud(){
  FILE *fp;
  char path[MIL];

  log_string("Saving Mud Data...");
  fclose(fpReserve);
  sprintf(path, "%s%s",SAVEMUD_DIR, SAVEMUD_FILE);
  if ((fp = fopen(path,"w")) == NULL){
    bug("save_mud: could not open SAVEMUD_FILE for write.", 0);
    perror(path);
    fpReserve = fopen( NULL_FILE, "r" );
    return;
  }
/* about to save print the time etc*/
  strcpy( mud_data.str_save_time, ctime( &mud_data.current_time ) );
  mud_data.save_time = mud_data.current_time;

/* have save file to be written too */
  if (!fwrite_mud( fp )){
    bug("save_mud: error occured while saving mud data. Removing savefile.", 0);
    fclose( fp );
    fpReserve = fopen( NULL_FILE, "r" );
    remove( path );
    log_string("Saving Mud Data: FAILURE...");
    return;
  }

/* close the file */
  fclose( fp );
  fpReserve = fopen( NULL_FILE, "r" );
}

/* resets the global mud data to initial values */
void reset_mdata(){

/* bools */
  mud_data.wizlock	= FALSE;
  mud_data.newlock	= FALSE;

/* statistics */
  mud_data.max_on	= 0;
  mud_data.deaths	= 0;
  mud_data.pfiles	= 0;
  mud_data.bounties	= 0;
  mud_data.siege_iden	= 0;
  mud_data.tot_bastion	= 1;

/* time */
  log_string("Initializing MUD system time...");
  mud_data.crash_time = mud_data.current_time;
  mud_data.save_time = 0;

/* strings*/
  log_string("Initializing MUD system strings...");
  strcpy( mud_data.str_boot_time, ctime( &mud_data.crash_time ) );
  strcpy( mud_data.str_save_time, ctime( &mud_data.save_time ) );

/* mud time */
  log_string("Initializing MUD calendar/time...");
  mud_data.time_info.hour	= 0;
  update_mud_time( mud_data.current_time );

  log_string("Initializing MUD weather and lightlevel...");
  if      ( mud_data.time_info.hour <  5 ) 
    mud_data.weather_info.sunlight = SUN_DARK;
  else if ( mud_data.time_info.hour <  6 ) 
    mud_data.weather_info.sunlight = SUN_RISE;
  else if ( mud_data.time_info.hour < 19 ) 
    mud_data.weather_info.sunlight = SUN_LIGHT;
  else if ( mud_data.time_info.hour < 20 ) 
    mud_data.weather_info.sunlight = SUN_SET;
  else                            
    mud_data.weather_info.sunlight = SUN_DARK;

  mud_data.weather_info.change	= 0;
  mud_data.weather_info.mmhg	= 960;

  if ( mud_data.time_info.month >= 7 && mud_data.time_info.month <=12 )
    mud_data.weather_info.mmhg += number_range( 1, 50 );
  else
    mud_data.weather_info.mmhg += number_range( 1, 80 );

  if ( mud_data.weather_info.mmhg <=  980 ) 
    mud_data.weather_info.sky = SKY_LIGHTNING;
  else if ( mud_data.weather_info.mmhg <= 1000 ) 
    mud_data.weather_info.sky = SKY_RAINING;
  else if ( mud_data.weather_info.mmhg <= 1020 ) 
    mud_data.weather_info.sky = SKY_CLOUDY;
  else                                  
    mud_data.weather_info.sky = SKY_CLOUDLESS;

/* QUESTS */
  mud_data.questor = str_dup( "" );
  mud_data.max_quest = 1;
  mud_data.last_questor = mud_data.current_time;

  log_string("Initialization complete...");
}


/* read the mud data from the save file passed */
bool fread_mud( FILE* fp ){
  int version = SAVEMUD_VER;
//  char buf[MSL];
  char *word = NULL;
  bool fMatch = FALSE;

  for ( ; ; ){
    /* check for eof */
    word   = feof( fp ) ? "End" : fread_word( fp );

    if (word == NULL)
      return FALSE;

    /* reset match */
    fMatch = FALSE;
    
    /* match current word */
    switch ( UPPER(word[0]) ){
    case '*':
      fMatch = TRUE;
      fread_to_eol( fp );
      break;
    case 'B':
      KEY( "bounties", mud_data.bounties, fread_number( fp ) );
      break;
    case 'D':
      KEY( "deaths", mud_data.deaths, fread_number( fp ) );
      break;
    case 'E':
      if (!str_cmp(word, "END"))
	return TRUE;
      break;
    case 'M':
      KEY( "max_on", mud_data.max_on, fread_number( fp ) );
      break;
    case 'N':
      KEY( "NEWLOCK", mud_data.newlock, TRUE );
      break;
    case 'P':
      if (!str_cmp(word, "Pact")){
	load_pact( fp );
	fMatch = TRUE;
	break;
      }
      KEY( "pfiles", mud_data.pfiles, fread_number( fp ) );
      break;
    case 'Q':
      if (!str_cmp(word, "Questor")){
	mud_data.questor	= fread_string( fp );
	mud_data.max_quest	= fread_number( fp );
	mud_data.last_questor	= fread_number( fp );
	mud_data.max_quest = UMAX(1, mud_data.max_quest);
	fMatch = TRUE;
	break;
      }
      break;
    case 'S':
      KEY( "sieges", mud_data.siege_iden, fread_number( fp ) );
    case 'T':
      KEY( "t_crash", mud_data.crash_time, fread_number( fp ) );
      KEY( "t_save", mud_data.save_time, fread_number( fp ) );
      if (!str_cmp(word, "t_mud")){
	mud_data.time_info.hour	= fread_number( fp );
	mud_data.time_info.day	= fread_number( fp );
	mud_data.time_info.month= fread_number( fp );
	mud_data.time_info.year	= fread_number( fp );

	update_mud_time( mud_data.current_time );
	fMatch = TRUE;
	break;
      }
      break;
    case 'V':
      KEY( "VERSION", version, fread_number( fp ) );
      if (!str_cmp(word, "Vote")){
	VOTE_DATA* pv = new_vote();
	read_vote( fp, pv );
	add_vote( pv );
	fMatch = TRUE;
	break;
      }
      break;
    case 'W':
      KEY( "WIZLOCK", mud_data.wizlock, TRUE );
      if (!str_cmp(word, "weather")){
	mud_data.weather_info.mmhg	= fread_number( fp );
	mud_data.weather_info.change	= fread_number( fp );
	mud_data.weather_info.sky	= fread_number( fp );
	mud_data.weather_info.sunlight	= fread_number( fp );
	fMatch = TRUE;
	break;
      }
      break;
    }
    if ( !fMatch ){
      bugf("Fread_mud: [%s] no match.", word);
      fread_to_eol( fp );
    }      
  }
  return FALSE; 
}

/* opens the SAVEMUD_FILE for read calls the read functions, */
/* closes it when done					      */
void read_mud(){
  FILE *fp;
  char path[MIL];

  log_string("Restoring Mud Data...");
/* look for save file */
  fclose(fpReserve);
  sprintf(path, "%s%s",SAVEMUD_DIR, SAVEMUD_FILE);

  if ((fp = fopen(path,"r")) == NULL){
    bug("read_mud: SAVEMUD_FILE not found, continuing with defaults.", 0);
    perror(path);
    fpReserve = fopen( NULL_FILE, "r" );
    return;
  }

/* begin reading */
  if (!fread_mud( fp )){
    bug("read_mud: error occured while reading mud data.", 0);
    log_string("Restoring Mud Data: FAILURE...");
  }

/* close the file */
  fclose( fp );
  fpReserve = fopen( NULL_FILE, "r" );
}