//----------------------------------------------------------------------------- // // $Logfile:: /Code/DLLs/game/gamescript.h $ // $Revision:: 4 $ // $Author:: Steven $ // $Date:: 10/13/03 8:54a $ // // 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. // // // 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 GameScriptMarker : public Class { public: CLASS_PROTOTYPE( GameScriptMarker ); str filename; scriptmarker_t scriptmarker; virtual void Archive( Archiver &arc ); }; inline 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.ArchiveString( &filename ); arc.ArchiveBoolean( &scriptmarker.tokenready ); arc.ArchiveInteger( &scriptmarker.offset ); arc.ArchiveInteger( &scriptmarker.line ); arc.ArchiveRaw( scriptmarker.token, sizeof( scriptmarker.token ) ); } class 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 ); }; class ScriptLibrarian : public Class { protected: Container scripts; str dialog_script; str game_script; public: CLASS_PROTOTYPE( ScriptLibrarian ); ~ScriptLibrarian(); void CloseScripts( void ); void SetDialogScript( const str &scriptname ); void SetGameScript( const 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 ); }; inline void ScriptLibrarian::Archive ( Archiver &arc ) { GameScript * scr; int i, num; Class::Archive( arc ); if ( arc.Loading() ) { scripts.FreeObjectList(); } else { num = scripts.NumObjects(); } arc.ArchiveInteger( &num ); for ( i = 1; i <= num; i++ ) { if ( arc.Saving() ) { scr = scripts.ObjectAt( i ); } else { scr = new GameScript; } arc.ArchiveObject( scr ); if ( arc.Loading() ) { scripts.AddObject( scr ); } } arc.ArchiveString( &dialog_script ); arc.ArchiveString( &game_script ); } extern ScriptLibrarian ScriptLib; inline 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; if ( arc.Saving() ) { arc.ArchiveUnsigned( &crc ); Mark( &mark ); arc.ArchiveObject( &mark ); } else { unsigned filecrc; GameScript *scr; arc.ArchiveUnsigned( &filecrc ); arc.ArchiveObject( &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( ERR_DROP, "File '%s' has changed from when this savegame was written. Load cancelled.\n", filename.c_str() ); } RestorePosition( &mark.scriptmarker ); } } #endif