/*=========================================================================== * * DFSaveTree.H - Dave Humphrey (uesp@m0use.net), Tuesday, November 28, 2000 * *=========================================================================*/ #ifndef __DFSAVETREE_H #define __DFSAVETREE_H /* Required Includes */ #include "genutil.h" /*=========================================================================== * * Begin Defines * *=========================================================================*/ /* Default record sizes */ #define DFSAVETREE_HEADER_SIZE sizeof(dfsavetree_header_t) #define DFSAVETREE_RECORDHEADER_SIZE sizeof(dfsavetree_recordheader_t) #define DFSAVETREE_GUILD_SIZE sizeof(dfsavetree_guild_t) /* Number of records allowed in a SAVETREE.DAT file. Code * enforced, not Daggerfall. */ #define DFSAVETREE_MAX_RECORDS 1500 /* Record size factor for dungeon records */ #define DFSAVETREE_DUNGEON_FACTOR 0x27 /*=========================================================================== * End of Defines *=========================================================================*/ /*=========================================================================== * * Begin Type and Structure Definitions * *=========================================================================*/ /* Ensure proper structure sizes */ #ifdef _WIN32 #pragma pack(push, save_pack) #pragma pack(1) #endif /* SaveTree.DAT header structure, 13 bytes */ typedef struct { long NumRecords; short Unknown1; short Unknown2; long Unknown3; short Unknown4; long Unknown5; byte Unknown6; } dfsavetree_header_t; /* Base record header data, 46 bytes */ typedef struct { short Unknown1; short Unknown2; short Unknown3; long XPosition; long YPosition; long ZPosition; short Unknown4; short Unknown5; long Unknown6; long Unknown7; long ObjectID; short Unknown8; byte Unknown9; byte QuestID; long ParentID; long Unknown10; long Unknown11; long Unknown12; long Unknown13; long Unknown14; long Unknown15; byte ParentType; byte Unknown16; short Unknown17; } dfsavetree_recordheader_t; /* Known guild information */ typedef struct { short Level; byte Unknown1; short GuildID; long Time1; long Time2; } dfsavetree_guild_t; #ifdef _WIN32 #pragma pack(pop, save_pack) #endif /*=========================================================================== * End of Type and Structure Definitions *=========================================================================*/ /*=========================================================================== * * Class CDFSaveTreeRecord Definition * *=========================================================================*/ class CDFSaveTreeRecord { /*---------- Begin Protected Class Members ---------------------*/ protected: long RecordOffset; /* Record offset in the SaveTree file */ long RecordSize; /* Size of the record */ byte RecordType; /* The type of record */ byte* pData; /* The raw record data */ boolean HeaderInput; /* Indicates that the header information has been read */ boolean Tagged; /* Used for sorting and comparing records */ /*---------- Begin Protected Class Methods ---------------------*/ protected: /* Compare records helper functions */ virtual boolean CompareRawData (CDFSaveTreeRecord* pRecord); virtual boolean CompareRecordSize (CDFSaveTreeRecord* pRecord); virtual boolean CompareRecordType (CDFSaveTreeRecord* pRecord); virtual boolean CompareRecordHeader (CDFSaveTreeRecord* pRecord) { return (TRUE); } virtual boolean CompareRecordData (CDFSaveTreeRecord* pRecord) { return (TRUE); } /* Input the record data */ virtual boolean ReadHeader (FILE* pFileHandle); virtual boolean ReadRecordHeader (FILE* pFileHandle) { return (TRUE); } virtual boolean ReadType (FILE* pFileHandle); virtual boolean ReadRawData (FILE* pFileHandle); /*---------- Begin Public Class Methods ------------------------*/ public: /* Class Constructor/Destructor */ CDFSaveTreeRecord(); virtual ~CDFSaveTreeRecord() { Destroy(); } virtual void Destroy (void); /* Compares records */ virtual boolean Compare (CDFSaveTreeRecord* pRecord); /* Check for zero-sized records */ virtual boolean IsEmpty (void) { return (IsZeroSized()); } virtual boolean IsZeroSized (void) { return (boolean) (RecordSize == 0); } /* Check the tagged state of the record */ virtual boolean IsTagged (void) { return (Tagged); } /* Get class members */ virtual long GetRecordSize (void) { return (RecordSize); } virtual long GetRecordOffset (void) { return (RecordOffset); } virtual byte GetRecordType (void) { return (RecordType); } virtual byte* GetRawData (void) { return (pData); } virtual long GetObjectID (void) { return (-1); } /* Get the record header data */ virtual dfsavetree_recordheader_t* GetRecordHeader (void) { return (NULL); } /* Get the real record size of the data */ virtual long GetRawDataSize (void) { return (RecordSize - 1); } /* Determine if the header has been input yet */ virtual boolean HasReadHeader (void) { return (HeaderInput); } /* Read in the raw record data */ virtual boolean Read (FILE* pFileHandle); /* Set class members */ virtual void SetReadHeader (const boolean Value) { HeaderInput = Value; } virtual void SetRecordSize (const long Size) { RecordSize = Size; } virtual void SetRecordOffset (const long Offset) { RecordOffset = Offset; } virtual void SetRecordType (const byte Type) { RecordType = Type; } virtual void SetTag (const Value = TRUE) { Tagged = Value; } }; /*=========================================================================== * End of Class CDFSaveTreeRecord Definition *=========================================================================*/ /*=========================================================================== * * Class CDFSaveTreeBase Definition * * Derived class for a regular SaveTree record. * *=========================================================================*/ class CDFSaveTreeBase : public CDFSaveTreeRecord { /*---------- Begin Protected Class Members ---------------------*/ protected: dfsavetree_recordheader_t RecordHeader; /*---------- Begin Protected Class Methods ---------------------*/ protected: /* Copare the record header */ boolean CompareRecordHeader (CDFSaveTreeRecord* pRecord); /* Read the record header data */ boolean ReadRecordHeader (FILE* pFileHandle); /*---------- Begin Public Class Methods ------------------------*/ public: /* Class Constructor/Destructor */ CDFSaveTreeBase(); void Destroy (void); /* Get the real record size of the data */ long GetRawDataSize (void) { return (RecordSize - 1 - DFSAVETREE_RECORDHEADER_SIZE); } long GetObjectID (void) { return (RecordHeader.ObjectID); } /* Get the record header data */ dfsavetree_recordheader_t* GetRecordHeader (void) { return (&RecordHeader); } }; /*=========================================================================== * End of Class CDFSaveTreeBase Definition *=========================================================================*/ /*=========================================================================== * * Class CDFSaveTreeNULL Definition * * Derived class for NULL, or 0 sized, SaveTree records. * *=========================================================================*/ class CDFSaveTreeNULL : public CDFSaveTreeRecord { /*---------- Begin Protected Class Methods ---------------------*/ protected: /* No type or raw data for NULL records */ boolean ReadType (FILE* pFileHandle) { return (TRUE); } boolean ReadRawData (FILE* pFileHandle) { return (TRUE); } /*---------- Begin Public Class Methods ------------------------*/ public: /* No use comparing NULL records */ boolean Compare (CDFSaveTreeRecord* pRecord) { return (TRUE); } /* Get the size of the raw town data */ long GetRawDataSize (void) { return (0); } }; /*=========================================================================== * End of Class CDFSaveTreeNULL Definition *=========================================================================*/ /*=========================================================================== * * Class CDFSaveTreeTown Definition * * Derived class for town SaveTree records. * *=========================================================================*/ class CDFSaveTreeTown : public CDFSaveTreeRecord { /*---------- Begin Protected Class Methods ---------------------*/ protected: /* No type field for town records */ boolean CompareRecordType (CDFSaveTreeRecord* pRecord) { return (TRUE); } /* No type field for town records */ boolean ReadType (FILE* pFileHandle) { return (TRUE); } /*---------- Begin Public Class Methods ------------------------*/ public: /* Get the size of the raw town data */ long GetRawDataSize (void) { return (RecordSize); } }; /*=========================================================================== * End of Class CDFSaveTreeTown Definition *=========================================================================*/ /*=========================================================================== * * Class CDFSaveTreeDungeon Definition * * Derived class for dungeon SaveTree records. * *=========================================================================*/ class CDFSaveTreeDungeon : public CDFSaveTreeRecord { /*---------- Begin Protected Class Methods ---------------------*/ protected: /* No type field for dungeon records */ boolean CompareRecordType (CDFSaveTreeRecord* pRecord) { return (TRUE); } /* No type field for dungeon records */ boolean ReadType (FILE* pFileHandle) { return (TRUE); } /*---------- Begin Public Class Methods --------------------------*/ public: /* Get the real record size of the dungeon data */ long GetRawDataSize (void) { return (RecordSize*DFSAVETREE_DUNGEON_FACTOR); } }; /*=========================================================================== * End of Class CDFSaveTreeDungeon Definition *=========================================================================*/ /*=========================================================================== * * Class CDFSaveTreeGuild Definition * *=========================================================================*/ class CDFSaveTreeGuild : public CDFSaveTreeBase { /*---------- Begin Protected Class Members ---------------------*/ protected: dfsavetree_guild_t GuildData; /*---------- Begin Protected Class Methods ---------------------*/ protected: /* Compare the guild data */ boolean CompareRecordData (CDFSaveTreeRecord* pRecord); /* Read the giuld and raw data */ boolean ReadRawData (FILE* pFileHandle); /*---------- Begin Public Class Methods ------------------------*/ public: /* Class Constructor/Destructor */ CDFSaveTreeGuild() { memset(&GuildData, 0, DFSAVETREE_GUILD_SIZE); } void Destroy (void) { memset(&GuildData, 0, DFSAVETREE_GUILD_SIZE); CDFSaveTreeBase::Destroy(); } /* Get the real record size of the data */ virtual long GetRawDataSize (void) { return (RecordSize - 1 - DFSAVETREE_RECORDHEADER_SIZE - DFSAVETREE_GUILD_SIZE); } /* Get the guild data pointer */ virtual dfsavetree_guild_t* GetGuildData (void) { return (&GuildData); } }; /*=========================================================================== * End of Class CDFSaveTreeGuild *=========================================================================*/ /*=========================================================================== * * Class CDFSaveTree Definition * * Class for manipulating the SAVETREE.DAT file which contains character * savegame information. * *=========================================================================*/ class CDFSaveTree { /*---------- Begin Protected Class Members ---------------------*/ protected: dfsavetree_header_t Header; /* File header data */ /* The raw record data */ CDFSaveTreeRecord* pRecords[DFSAVETREE_MAX_RECORDS]; int NumRecords; /* Record index of the dungeon data (even if zero-length) */ int DungeonRecordIndex; int NumZeroSizedRecords; /*---------- Begin Protected Class Methods ---------------------*/ protected: /* Create the next SaveTree record */ virtual boolean CreateRecord (FILE* pFileHandle); /* Helper input functions */ virtual boolean ReadHeader (FILE* pFileHandle); virtual boolean ReadRecords (FILE* pFileHandle); /*---------- Begin Public Class Methods ------------------------*/ public: /* Class Constructor/Destructor */ CDFSaveTree(); virtual ~CDFSaveTree() { Destroy(); } virtual void Destroy (void); /* Compares two savetree files, record by record */ virtual boolean Compare (CDFSaveTree& SaveTree); /* Outputs any untagged records to the SystemLog file */ virtual boolean CompareOutputUntagged (void); /* Clears the tags of all the current records */ virtual void ClearTags (void); /* Search for an ObjectID in the record array */ virtual int FindObjectID (const long ObjectID); /* Get class members */ virtual int GetNumRecords (void) { return (NumRecords); } virtual int GetDungeonIndex (void) { return (DungeonRecordIndex); } virtual int GetNumZeroRecords (void) { return (NumZeroSizedRecords); } /* Get a particular record pointer */ virtual CDFSaveTreeRecord* GetRecord (const int Index) { if (IsValidIndex(Index)) return (pRecords[Index]); return (NULL); } /* Get specific records */ virtual CDFSaveTreeTown* GetTownRecord (void) { if (NumRecords < 1) return (NULL); return ((CDFSaveTreeTown*) pRecords[0]); } virtual CDFSaveTreeDungeon* GetDungeonRecord (void) { if (DungeonRecordIndex < 0) return (NULL); return ((CDFSaveTreeDungeon*) pRecords[DungeonRecordIndex]); } /* Check a record index for validity */ virtual boolean IsValidIndex (const int Index) { return ((Index >= 0 && Index < NumRecords) ? TRUE : FALSE); } /* Load a SaveTree.DAT file */ virtual boolean Load (const char* pFilename); }; /*=========================================================================== * End of Class CDFSaveTree Definition *=========================================================================*/ /*=========================================================================== * * Begin Function Prototypes * *=========================================================================*/ /* Convert a record type to a string */ char* DFGetSaveTreeType (const int Type); /*=========================================================================== * End of Function Prototypes *=========================================================================*/ #endif /*=========================================================================== * End of File DFSaveTree.H *=========================================================================*/