//----------------------------------------------------------------------------- // // $Logfile:: /Quake 2 Engine/Sin/code/game/gamescript.h $ // $Revision:: 11 $ // $Author:: Jimdose $ // $Date:: 10/25/98 11:53p $ // // Copyright (C) 1997 by Ritual Entertainment, Inc. // All rights reserved. // // This source is may not be distributed and/or modified without // expressly written permission by Ritual Entertainment, Inc. // // $Log:: /Quake 2 Engine/Sin/code/game/gamescript.h $ // // 11 10/25/98 11:53p Jimdose // added EXPORT_TEMPLATE // // 10 10/20/98 10:30p Jimdose // added crc checking to unarchive // // 9 10/07/98 11:50p Jimdose // Rewrote archiving functions for savegames // got rid of type // // 8 9/22/98 1:49a Jimdose // removed freelabels // // 7 9/21/98 10:15p Markd // Putting archiving and unarchiving functions in // // 6 7/13/98 5:57p Markd // Added Setgamescript and Getgamescript methods // // 5 7/11/98 8:43p Markd // Added SetDialogScript // // 4 7/07/98 11:36p Jimdose // Added GameScriptMarker // // 3 6/09/98 4:24p Jimdose // finished implimentation // // 2 6/05/98 2:37p Jimdose // Created file // // DESCRIPTION: // Subclass of script that preprocesses labels // #ifndef __GAMESCRIPT_H__ #define __GAMESCRIPT_H__ #include "class.h" #include "script.h" typedef struct { scriptmarker_t pos; str labelname; } script_label_t; class GameScript; class EXPORT_FROM_DLL GameScriptMarker : public Class { public: CLASS_PROTOTYPE( GameScriptMarker ); str filename; scriptmarker_t scriptmarker; virtual void Archive( Archiver &arc ); virtual void Unarchive( Archiver &arc ); }; inline EXPORT_FROM_DLL void GameScriptMarker::Archive ( Archiver &arc ) { // Game scripts are unique in that we don't call our superclass to archive it's data. // Instead, we only read enough info to then initialize the script ourselves. arc.WriteString( filename ); arc.WriteBoolean( scriptmarker.tokenready ); arc.WriteInteger( scriptmarker.offset ); arc.WriteInteger( scriptmarker.line ); arc.WriteRaw( scriptmarker.token, sizeof( scriptmarker.token ) ); } inline EXPORT_FROM_DLL void GameScriptMarker::Unarchive ( Archiver &arc ) { // Game scripts are unique in that we don't call our superclass to archive it's data. // Instead, we only read enough info to then initialize the script ourselves. arc.ReadString( &filename ); arc.ReadBoolean( &scriptmarker.tokenready ); arc.ReadInteger( &scriptmarker.offset ); arc.ReadInteger( &scriptmarker.line ); arc.ReadRaw( scriptmarker.token, sizeof( scriptmarker.token ) ); } #ifdef EXPORT_TEMPLATE template class EXPORT_FROM_DLL Container; #endif class EXPORT_FROM_DLL GameScript : public Script { protected: Container *labelList; GameScript *sourcescript; unsigned crc; public: CLASS_PROTOTYPE( GameScript ); GameScript(); GameScript( GameScript *scr ); ~GameScript(); void Close( void ); void SetSourceScript( GameScript *scr ); void LoadFile( const char *filename ); void Mark( GameScriptMarker *mark ); void Restore( GameScriptMarker *mark ); void FreeLabels( void ); void FindLabels( void ); qboolean labelExists( const char *name ); qboolean Goto( const char *name ); virtual void Archive( Archiver &arc ); virtual void Unarchive( Archiver &arc ); }; #ifdef EXPORT_TEMPLATE template class EXPORT_FROM_DLL Container; #endif class EXPORT_FROM_DLL ScriptLibrarian : public Class { protected: Container scripts; str dialog_script; str game_script; public: CLASS_PROTOTYPE( ScriptLibrarian ); ~ScriptLibrarian(); void CloseScripts( void ); void SetDialogScript( str scriptname ); void SetGameScript( str scriptname ); const char *GetGameScript( void ); GameScript *FindScript( const char *name ); GameScript *GetScript( const char *name ); qboolean Goto( GameScript *scr, const char *name ); qboolean labelExists( GameScript *scr, const char *name ); virtual void Archive( Archiver &arc ); virtual void Unarchive( Archiver &arc ); }; inline EXPORT_FROM_DLL void ScriptLibrarian::Archive ( Archiver &arc ) { GameScript * scr; int i, num; Class::Archive( arc ); num = scripts.NumObjects(); arc.WriteInteger( num ); for ( i = 1; i <= num; i++ ) { scr = scripts.ObjectAt( i ); arc.WriteObject( scr ); } arc.WriteString( dialog_script ); arc.WriteString( game_script ); } inline EXPORT_FROM_DLL void ScriptLibrarian::Unarchive ( Archiver &arc ) { GameScript * scr; int i, num; Class::Unarchive( arc ); scripts.FreeObjectList(); arc.ReadInteger( &num ); for ( i = 1; i <= num; i++ ) { scr = new GameScript; arc.ReadObject( scr ); scripts.AddObject( scr ); } arc.ReadString( &dialog_script ); arc.ReadString( &game_script ); } extern ScriptLibrarian ScriptLib; inline EXPORT_FROM_DLL void GameScript::Archive ( Archiver &arc ) { // Game scripts are unique in that we don't call our superclass to archive it's data. // Instead, we only read enough info to then initialize the script ourselves. GameScriptMarker mark; arc.WriteUnsigned( crc ); Mark( &mark ); arc.WriteObject( &mark ); } inline EXPORT_FROM_DLL void GameScript::Unarchive ( Archiver &arc ) { // This function is based in part on Restore, so it changes, we must update this function as well. // Game scripts are unique in that we don't call our superclass to archive it's data. // Instead, we only read enough info to then initialize the script ourselves. GameScriptMarker mark; unsigned filecrc; GameScript *scr; arc.ReadUnsigned( &filecrc ); arc.ReadObject( &mark ); scr = ScriptLib.FindScript( mark.filename.c_str() ); if ( scr ) { SetSourceScript( scr ); } else { LoadFile( mark.filename.c_str() ); } // Error out if CRCs have changed if ( filecrc != crc ) { gi.error( "File '%s' has changed from when this savegame was written. Load cancelled.\n", filename.c_str() ); } RestorePosition( &mark.scriptmarker ); } #endif