/*
* Copyright (C) 1995-1997 Christopher D. Granz
*
* This header may not be removed.
*
* Refer to the file "License" included in this package for further
* information and before using any of the following.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "sapphire.h"
/*
* Prototypes
*/
#define OD OBJ_DATA
static void fprint_pc_data ( FILE *, CHAR_DATA * );
static void fprint_stats ( FILE *, STAT_DATA * );
static void fprint_known ( FILE *, CHAR_DATA * );
static void fprint_object ( FILE *, OBJ_DATA * );
static void fread_pc_data ( FILE *, CHAR_DATA * );
static void fread_stats ( FILE *, STAT_DATA * );
static void fread_known ( FILE *, CHAR_DATA * );
static OD * fread_object ( FILE *, CHAR_DATA * );
#undef OD
/*
* Globals
*/
ROOM_INDEX_DATA * pStartingRoom;
/*
* Functions
*/
/*
* Save one PC to file.
*/
void save_pc( CHAR_DATA *pChar )
{
/* OBJ_DATA *pObj; */
FILE *pFile;
char cFilename[MAX_INPUT];
if ( IS_NPC( pChar ) || IS_GUEST( pChar ) )
return;
sprintf( cFilename, "%s%s.plr", pPlayerDir,
capit( pChar->pPCData->sName ) );
pFile = open_file( cFilename, "w", TRUE );
fprintf( pFile, "@PC_DATA\n" );
fprint_pc_data( pFile, pChar );
fprintf( pFile, "\n@STATS\n" );
fprint_stats( pFile, pChar->pStats );
fprintf( pFile, "\n@KNOWN\n" );
fprint_known( pFile, pChar );
/* for ( pObj = pChar->pInven; pObj; pObj = pObj->pNextContent )
{
fprintf( pFile, "\n@ITEM\n" );
fprint_object( pFile, pObj );
} */
fprintf( pFile, "\n@END\n" );
close_file( pFile );
}
/*
* Load one PC from file.
*/
CHAR_DATA *load_pc( char *pName )
{
char cFilename[MAX_INPUT];
CHAR_DATA *pChar;
FILE *pFile;
char *pBuf;
sprintf( cFilename, "%s%s.plr", pPlayerDir, capit( pName ) );
if ( ( pFile = open_file( cFilename, "r", FALSE ) ) == NULL )
return ( NULL );
pChar = new_pc( );
pChar->pPCData->sName = save_string( capit( pName ) );
for ( ; ; )
{
if ( fget_letter( pFile ) != '@' )
{
sap_error( "Symbol `@' missing from file." );
free_char( &pChar );
close_file( pFile );
return ( NULL );
}
pBuf = ( feof( pFile ) ? "END"
: fget_word( pFile ) );
if ( str_compare( pBuf, "PC_DATA" ) == TRUE )
fread_pc_data( pFile, pChar );
else if ( str_compare( pBuf, "STATS" ) == TRUE )
fread_stats( pFile, pChar->pStats );
else if ( str_compare( pBuf, "KNOWN" ) == TRUE )
fread_known( pFile, pChar );
else if ( str_compare( pBuf, "ITEM" ) == TRUE )
{
OBJ_DATA *pObj = fread_object( pFile, pChar );
pObj->pCarriedBy = pChar;
pObj->pNextContent = pChar->pInven;
pChar->pInven = pObj;
}
else if ( str_compare( pBuf, "END" ) == TRUE )
{
close_file( pFile );
return ( pChar );
}
else
{
sap_error( "Unknown section `%s'.", pBuf );
close_file( pFile );
free_char( &pChar );
return ( NULL );
}
}
close_file( pFile );
return ( NULL );
}
static void fprint_pc_data( FILE *pFile, CHAR_DATA *pChar )
{
fprintf( pFile, "LL %ld\n", pChar->pPCData->tLastLogin );
if ( pChar->pPCData->sPassword[0] != '\0' )
{
fprintf( pFile, "PW " );
fput_string( pFile, "%s", pChar->pPCData->sPassword );
fputc( '\n', pFile );
}
if ( pChar->pPCData->sPrompt[0] != '\0' )
{
fprintf( pFile, "P " );
fput_string( pFile, "%s", pChar->pPCData->sPrompt );
fputc( '\n', pFile );
}
if ( pChar->sLongDesc[0] != '\0' )
{
fprintf( pFile, "LD " );
fput_string( pFile, "%s", pChar->sLongDesc );
putc( '\n', pFile );
}
if ( pChar->fPartFlags != 0 )
fprintf( pFile, "PF %ld\n", pChar->fPartFlags );
if ( pChar->fActFlags != 0 )
fprintf( pFile, "AF %ld\n", pChar->fActFlags );
if ( pChar->pPCData->fChanFlags != 0 )
fprintf( pFile, "CF %ld\n", pChar->pPCData->fChanFlags );
if ( pChar->iLevel != 0 )
fprintf( pFile, "L %d\n", pChar->iLevel );
if ( pChar->iAlignment != 0 )
fprintf( pFile, "A %d\n", pChar->iAlignment );
if ( pChar->iRace != 0 )
fprintf( pFile, "R %d\n", pChar->iRace );
if ( pChar->iSex != 0 )
fprintf( pFile, "S %d\n", pChar->iSex );
if ( pChar->iHairColor != 0 )
fprintf( pFile, "HC %d\n", pChar->iHairColor );
if ( pChar->iEyeColor != 0 )
fprintf( pFile, "EC %d\n", pChar->iEyeColor );
if ( pChar->iHeight != 0 )
fprintf( pFile, "H %d\n", pChar->iHeight );
if ( pChar->iWeight != 0 )
fprintf( pFile, "W %d\n", pChar->iWeight );
if ( pChar->iMaxCarry != 0 )
fprintf( pFile, "MC %d\n", pChar->iMaxCarry );
if ( pChar->iHP != 0 )
fprintf( pFile, "HP %d\n", pChar->iHP );
if ( pChar->iMP != 0 )
fprintf( pFile, "MP %d\n", pChar->iMP );
if ( pChar->iMV != 0 )
fprintf( pFile, "MV %d\n", pChar->iMV );
if ( pChar->iPosition != 0 )
fprintf( pFile, "PO %d\n", pChar->iPosition );
if ( pChar->iGold != 0 )
fprintf( pFile, "G %ld\n", pChar->iGold );
if ( pChar->pInRoom != NULL && pChar->pInRoom != uDefaultRoom.pRoom )
fprintf( pFile, "RO %ld\n", pChar->pInRoom->iNumber );
fprintf( pFile, "END\n" );
}
static void fprint_stats( FILE *pFile, STAT_DATA *pStats )
{
if ( pStats->iStatStr != 0 )
fprintf( pFile, "S %d\n", pStats->iStatStr );
if ( pStats->iStatInt != 0 )
fprintf( pFile, "I %d\n", pStats->iStatInt );
if ( pStats->iStatWis != 0 )
fprintf( pFile, "W %d\n", pStats->iStatWis );
if ( pStats->iStatDex != 0 )
fprintf( pFile, "D %d\n", pStats->iStatDex );
if ( pStats->iStatCon != 0 )
fprintf( pFile, "C %d\n", pStats->iStatCon );
if ( pStats->iStatCha != 0 )
fprintf( pFile, "CH %d\n", pStats->iStatCha );
if ( pStats->iStatLuc != 0 )
fprintf( pFile, "L %d\n", pStats->iStatLuc );
if ( pStats->iStatHP != 0 )
fprintf( pFile, "HP %d\n", pStats->iStatHP );
if ( pStats->iStatMP != 0 )
fprintf( pFile, "MP %d\n", pStats->iStatMP );
if ( pStats->iStatMV != 0 )
fprintf( pFile, "MV %d\n", pStats->iStatMV );
fprintf( pFile, "END\n" );
}
static void fprint_known( FILE *pFile, CHAR_DATA *pChar )
{
KNOWN_PERSON_DATA *pKnownPerson;
KNOWN_EXIT_DATA *pKnownExit;
if ( IS_NPC( pChar ) || pChar->iLevel >= BUILDER_LEVEL )
{
fprintf( pFile, "END\n" );
return;
}
for ( pKnownPerson = pChar->pPCData->pKnownPeople; pKnownPerson;
pKnownPerson = pKnownPerson->pNext )
{
fprintf( pFile, "P " );
fput_string( pFile, "%s", pKnownPerson->sName );
fprintf( pFile, " %ld\n", (long) pKnownPerson->tIntroduced );
}
for ( pKnownExit = pChar->pPCData->pKnownExits; pKnownExit != NULL;
pKnownExit = pKnownExit->pNext )
{
fprintf( pFile, "E %ld %d %ld\n", pKnownExit->pRoom->iNumber,
(int) pKnownExit->iDir, (long) pKnownExit->tDiscovered );
}
fprintf( pFile, "END\n" );
}
static void fprint_object( FILE *pFile, OBJ_DATA *pObj )
{
fprintf( pFile, "NUMBER %ld\n", pObj->pObjIndex->iNumber );
fprintf( pFile, "END\n" );
}
static void fread_pc_data( FILE *pFile, CHAR_DATA *pChar )
{
char *pBuf;
int i, i2;
bool bFoundMatch;
for ( ; ; )
{
bFoundMatch = FALSE;
pBuf = fget_word( pFile );
if ( str_compare( pBuf, "END" ) == TRUE )
break;
KEY( "LASTLOGIN", pChar->pPCData->tLastLogin,
fget_number( pFile ) );
KEY( "LL", pChar->pPCData->tLastLogin,
fget_number( pFile ) );
SSKEY( "PASSWORD", pChar->pPCData->sPassword,
fget_string( pFile ) );
SSKEY( "PW", pChar->pPCData->sPassword,
fget_string( pFile ) );
SSKEY( "PROMPT", pChar->pPCData->sPrompt,
fget_string( pFile ) );
SSKEY( "P", pChar->pPCData->sPrompt,
fget_string( pFile ) );
SSKEY( "LONGDESC", pChar->sLongDesc, fget_string( pFile ) );
SSKEY( "LD", pChar->sLongDesc, fget_string( pFile ) );
KEY( "PARTFLAGS", pChar->fPartFlags, fget_number( pFile ) );
KEY( "PF", pChar->fPartFlags, fget_number( pFile ) );
KEY( "ACTFLAGS", pChar->fActFlags, fget_number( pFile ) );
KEY( "AF", pChar->fActFlags, fget_number( pFile ) );
KEY( "CHANFLAGS", pChar->pPCData->fChanFlags,
fget_number( pFile ) );
KEY( "CF", pChar->pPCData->fChanFlags,
fget_number( pFile ) );
KEY( "LEVEL", pChar->iLevel, fget_number( pFile ) );
KEY( "L", pChar->iLevel, fget_number( pFile ) );
KEY( "ALIGNMENT", pChar->iAlignment, fget_number( pFile ) );
KEY( "A", pChar->iAlignment, fget_number( pFile ) );
KEY( "RACE", pChar->iRace, fget_number( pFile ) );
KEY( "R", pChar->iRace, fget_number( pFile ) );
KEY( "SEX", pChar->iSex, fget_number( pFile ) );
KEY( "S", pChar->iSex, fget_number( pFile ) );
KEY( "HAIRCOLOR", pChar->iHairColor, fget_number( pFile ) );
KEY( "HC", pChar->iHairColor, fget_number( pFile ) );
KEY( "EYECOLOR", pChar->iEyeColor, fget_number( pFile ) );
KEY( "EC", pChar->iEyeColor, fget_number( pFile ) );
KEY( "HEIGHT", pChar->iHeight, fget_number( pFile ) );
KEY( "H", pChar->iHeight, fget_number( pFile ) );
KEY( "WEIGHT", pChar->iWeight, fget_number( pFile ) );
KEY( "W", pChar->iWeight, fget_number( pFile ) );
KEY( "MAXCARRY", pChar->iMaxCarry, fget_number( pFile ) );
KEY( "MC", pChar->iMaxCarry, fget_number( pFile ) );
KEY( "HP", pChar->iHP, fget_number( pFile ) );
KEY( "MP", pChar->iMP, fget_number( pFile ) );
KEY( "MV", pChar->iMV, fget_number( pFile ) );
KEY( "POSITION", pChar->iPosition, fget_number( pFile ) );
KEY( "PO", pChar->iPosition, fget_number( pFile ) );
KEY( "GOLD", pChar->iGold, fget_number( pFile ) );
KEY( "G", pChar->iGold, fget_number( pFile ) );
KEY( "ROOM", pStartingRoom,
get_room_index( fget_number( pFile ) ) );
KEY( "RO", pStartingRoom,
get_room_index( fget_number( pFile ) ) );
if ( bFoundMatch != TRUE )
sap_warning( "No match for `%s'.", pBuf );
}
if ( pStartingRoom == NULL )
pStartingRoom = uDefaultRoom.pRoom;
if ( pChar->iLevel < 1 )
pChar->iLevel = 1;
else if ( pChar->iLevel > IMP_LEVEL )
pChar->iLevel = IMP_LEVEL;
if ( pChar->iAlignment < -1000 )
pChar->iAlignment = 1;
else if ( pChar->iAlignment > 1000 )
pChar->iAlignment = 1000;
if ( get_race_string( pChar->iRace )[0] == '\0' )
pChar->iRace = rRaceTable[0].iNumber;
if ( get_sex_string( pChar->iSex )[0] == '\0' )
pChar->iSex = snSexTable[0].iNumber;
i = get_race_index( pChar->iRace );
for ( i2 = 0; rRaceTable[i].iHairColors[i2] != 0; i2++ )
{
if ( rRaceTable[i].iHairColors[i2] == pChar->iHairColor )
break;
}
if ( rRaceTable[i].iHairColors[i2] == 0 )
pChar->iHairColor = rRaceTable[i].iHairColors[0];
for ( i2 = 0; rRaceTable[i].iEyeColors[i2] != 0; i2++ )
{
if ( rRaceTable[i].iEyeColors[i2] == pChar->iEyeColor )
break;
}
if ( rRaceTable[i].iEyeColors[i2] == 0 )
pChar->iEyeColor = rRaceTable[i].iEyeColors[0];
if ( pChar->iHeight < rRaceTable[i].iUpperLowerHeights[1] )
pChar->iHeight = rRaceTable[i].iUpperLowerHeights[1];
else if ( pChar->iHeight > rRaceTable[i].iUpperLowerHeights[0] )
pChar->iHeight = rRaceTable[i].iUpperLowerHeights[0];
if ( pChar->iWeight < rRaceTable[i].iUpperLowerWeights[1] )
pChar->iWeight = rRaceTable[i].iUpperLowerWeights[1];
else if ( pChar->iWeight > rRaceTable[i].iUpperLowerWeights[0] )
pChar->iWeight = rRaceTable[i].iUpperLowerWeights[0];
if ( pChar->iHP < 0 )
pChar->iHP = 0;
else if ( pChar->iHP > 9999 )
pChar->iHP = 9999;
if ( pChar->iMP < 0 )
pChar->iMP = 0;
else if ( pChar->iMP > 9999 )
pChar->iMP = 9999;
if ( pChar->iMV < 0 )
pChar->iMV = 0;
else if ( pChar->iMV > 9999 )
pChar->iMV = 9999;
if ( pChar->iPosition != NUMBER_POSITION_DYING
&& pChar->iPosition != NUMBER_POSITION_SLEEPING
&& pChar->iPosition != NUMBER_POSITION_RESTING
&& pChar->iPosition != NUMBER_POSITION_SITTING
&& pChar->iPosition != NUMBER_POSITION_STANDING )
pChar->iPosition = NUMBER_POSITION_STANDING;
}
static void fread_stats( FILE *pFile, STAT_DATA *pStats )
{
char *pBuf;
bool bFoundMatch;
for ( ; ; )
{
bFoundMatch = FALSE;
pBuf = fget_word( pFile );
if ( str_compare( pBuf, "END" ) == TRUE )
break;
KEY( "STR", pStats->iStatStr, fget_number( pFile ) );
KEY( "S", pStats->iStatStr, fget_number( pFile ) );
KEY( "INT", pStats->iStatInt, fget_number( pFile ) );
KEY( "I", pStats->iStatInt, fget_number( pFile ) );
KEY( "WIS", pStats->iStatWis, fget_number( pFile ) );
KEY( "W", pStats->iStatWis, fget_number( pFile ) );
KEY( "DEX", pStats->iStatDex, fget_number( pFile ) );
KEY( "D", pStats->iStatDex, fget_number( pFile ) );
KEY( "CON", pStats->iStatCon, fget_number( pFile ) );
KEY( "C", pStats->iStatCon, fget_number( pFile ) );
KEY( "CHA", pStats->iStatCha, fget_number( pFile ) );
KEY( "CH", pStats->iStatCha, fget_number( pFile ) );
KEY( "LUC", pStats->iStatLuc, fget_number( pFile ) );
KEY( "L", pStats->iStatLuc, fget_number( pFile ) );
KEY( "HP", pStats->iStatHP, fget_number( pFile ) );
KEY( "MP", pStats->iStatMP, fget_number( pFile ) );
KEY( "MV", pStats->iStatMV, fget_number( pFile ) );
if ( bFoundMatch != TRUE )
sap_warning( "No match for `%s'.", pBuf );
}
if ( pStats->iStatStr < 0 )
pStats->iStatStr = 0;
else if ( pStats->iStatStr > 100 )
pStats->iStatStr = 100;
if ( pStats->iStatInt < 0 )
pStats->iStatInt = 0;
else if ( pStats->iStatInt > 100 )
pStats->iStatInt = 100;
if ( pStats->iStatWis < 0 )
pStats->iStatWis = 0;
else if ( pStats->iStatWis > 100 )
pStats->iStatWis = 100;
if ( pStats->iStatDex < 0 )
pStats->iStatDex = 0;
else if ( pStats->iStatDex > 100 )
pStats->iStatDex = 100;
if ( pStats->iStatCon < 0 )
pStats->iStatCon = 0;
else if ( pStats->iStatCon > 100 )
pStats->iStatCon = 100;
if ( pStats->iStatCha < 0 )
pStats->iStatCha = 0;
else if ( pStats->iStatCha > 100 )
pStats->iStatCha = 100;
if ( pStats->iStatLuc < 0 )
pStats->iStatLuc = 0;
else if ( pStats->iStatLuc > 100 )
pStats->iStatLuc = 100;
if ( pStats->iStatHP < 0 )
pStats->iStatHP = 0;
else if ( pStats->iStatHP > 100 )
pStats->iStatHP = 100;
if ( pStats->iStatMP < 0 )
pStats->iStatMP = 0;
else if ( pStats->iStatMP > 100 )
pStats->iStatMP = 100;
if ( pStats->iStatMV < 0 )
pStats->iStatMV = 0;
else if ( pStats->iStatMV > 100 )
pStats->iStatMV = 100;
}
static void fread_known( FILE *pFile, CHAR_DATA *pChar )
{
char *pBuf;
bool bFoundMatch;
for ( ; ; )
{
bFoundMatch = FALSE;
pBuf = fget_word( pFile );
if ( str_compare( pBuf, "END" ) == TRUE )
break;
if ( str_compare( pBuf, "PERSON" ) == TRUE
|| str_compare( pBuf, "P" ) == TRUE )
{
KNOWN_PERSON_DATA *pKnownPerson;
bFoundMatch = TRUE;
pKnownPerson = alloc_mem( sizeof( *pKnownPerson ) );
pKnownPerson->sName = save_string( fget_string( pFile ) );
pKnownPerson->tIntroduced = fget_number( pFile );
pKnownPerson->pNext = pChar->pPCData->pKnownPeople;
pChar->pPCData->pKnownPeople = pKnownPerson;
}
if ( str_compare( pBuf, "EXIT" ) == TRUE
|| str_compare( pBuf, "E" ) == TRUE )
{
ROOM_INDEX_DATA *pRoom;
KNOWN_EXIT_DATA *pKnownExit;
bFoundMatch = TRUE;
if ( ( pRoom = get_room_index( fget_number( pFile ) ) )
== NULL )
continue;
pKnownExit = alloc_mem( sizeof( *pKnownExit ) );
pKnownExit->pRoom = get_room_index( fget_number( pFile ) );
pKnownExit->tDiscovered = fget_number( pFile );
pKnownExit->pNext = pChar->pPCData->pKnownExits;
pChar->pPCData->pKnownExits = pKnownExit;
}
if ( bFoundMatch != TRUE )
sap_warning( "No match for `%s'.", pBuf );
}
}
static OBJ_DATA *fread_object( FILE *pFile, CHAR_DATA *pChar )
{
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *pObj = NULL;
char *pBuf;
int iNumber;
bool bFoundMatch;
for ( ; ; )
{
bFoundMatch = FALSE;
pBuf = fget_word( pFile );
if ( str_compare( pBuf, "END" ) == TRUE )
break;
if ( str_compare( pBuf, "NUMBER" ) == TRUE )
{
iNumber = atoi( pBuf );
if ( ( pObjIndex = get_object_index( iNumber ) ) == NULL )
sap_warning( "Unknown object number `%d'.", iNumber );
else
pObj = new_object( pObjIndex, pChar );
bFoundMatch = TRUE;
}
if ( bFoundMatch != TRUE )
sap_warning( "No match for `%s'.", pBuf );
}
return ( pObj );
}
/*
* End of plr_save.c
*/