/* * 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 */