diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 37fa2f76..792a46d6 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -23,7 +23,6 @@ GNU General Public License for more details. #include "library.h" #include "vid_common.h" #include "pm_local.h" -#include "sequence.h" #define MAX_TOTAL_CMDS 32 #define MAX_CMD_BUFFER 8000 @@ -233,9 +232,6 @@ void CL_SignonReply( void ) if( cl.proxy_redirect && !cls.spectator ) CL_Disconnect(); cl.proxy_redirect = false; - - if( cls.demoplayback ) - Sequence_OnLevelLoad( clgame.mapname ); break; } } @@ -3138,7 +3134,6 @@ void CL_Init( void ) VID_Init(); // init video S_Init(); // init sound Voice_Init( VOICE_DEFAULT_CODEC, 3 ); // init voice - Sequence_Init(); // unreliable buffer. unsed for unreliable commands and voice stream MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf )); diff --git a/engine/client/s_vox.c b/engine/client/s_vox.c index adf1642d..8ee8b81f 100644 --- a/engine/client/s_vox.c +++ b/engine/client/s_vox.c @@ -16,7 +16,6 @@ GNU General Public License for more details. #include "common.h" #include "sound.h" #include "const.h" -#include "sequence.h" #include static int cszrawsentences = 0; @@ -165,24 +164,11 @@ static const char *VOX_LookupString( const char *pszin ) int i = -1, len; const char *c; - // check if we are a CSCZ or immediate sentence + // check if we are an immediate sentence if( *pszin == '#' ) { - // Q_atoi is too smart and allows negative values - // so check with Q_isdigit beforehand - if( Q_isdigit( pszin + 1 )) - { - sentenceEntry_s *sentenceEntry; - i = Q_atoi( pszin + 1 ); - if(( sentenceEntry = Sequence_GetSentenceByIndex( i ))) - return sentenceEntry->data; - return NULL; - } - else - { - // immediate sentence, probably coming from "speak" command - return pszin + 1; - } + // immediate sentence, probably coming from "speak" command + return pszin + 1; } // check if we received an index diff --git a/engine/common/common.c b/engine/common/common.c index 7ff5c322..892e8ad1 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -22,7 +22,6 @@ GNU General Public License for more details. #include "const.h" #include "client.h" #include "library.h" -#include "sequence.h" static const char *file_exts[] = { @@ -1047,7 +1046,7 @@ void *GAME_EXPORT pfnSequenceGet( const char *fileName, const char *entryName ) { Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName ); - return Sequence_Get( fileName, entryName ); + return NULL; } /* @@ -1061,7 +1060,7 @@ void *GAME_EXPORT pfnSequencePickSentence( const char *groupName, int pickMethod { Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod ); - return Sequence_PickSentence( groupName, pickMethod, picked ); + return NULL; } diff --git a/engine/common/sequence.c b/engine/common/sequence.c deleted file mode 100644 index 187ced7b..00000000 --- a/engine/common/sequence.c +++ /dev/null @@ -1,1782 +0,0 @@ -/* -sequence.c - scripted sequences for CS:CZDS -Copyright (C) 2017 a1batross - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ - -#include -#include "common.h" -#include "eiface.h" -#include "sequence.h" - -sequenceCommandLine_s g_fileScopeDefaults; -sequenceCommandLine_s g_blockScopeDefaults; -sequenceEntry_s *g_sequenceList = NULL; -sentenceGroupEntry_s *g_sentenceGroupList = NULL; -qboolean g_sequenceParseFileIsGlobal; -unsigned int g_nonGlobalSentences = 0; -char g_sequenceParseFileName[MAX_STRING]; -int g_lineNum = 1; -char *g_scan = NULL; -char *g_lineScan = NULL; - -const sequenceCommandMapping_s g_sequenceCommandMappingTable[] = -{ - {SEQUENCE_COMMAND_PAUSE, "pause", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_TEXT, "text", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_SOUND, "sound", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_FIRETARGETS, "firetargets", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_KILLTARGETS, "killtargets", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_GOSUB, "gosub", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_SENTENCE, "sentence", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_REPEAT, "repeat", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_SETDEFAULTS, "setdefaults", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_MODIFIER, "modifier", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_POSTMODIFIER, "postmodifier", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_COMMAND_NOOP, "noop", SEQUENCE_TYPE_COMMAND}, - {SEQUENCE_MODIFIER_EFFECT, "effect", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_POSITION, "position", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_COLOR, "color", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_COLOR2, "color2", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_FADEIN, "fadein", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_FADEOUT, "fadeout", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_HOLDTIME, "holdtime", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_FXTIME, "fxtime", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_SPEAKER, "speaker", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_LISTENER, "listener", SEQUENCE_TYPE_MODIFIER}, - {SEQUENCE_MODIFIER_TEXTCHANNEL, "channel", SEQUENCE_TYPE_MODIFIER} -}; - -/* -============= -Sequence_GetCommandEnumForName - -============= -*/ -static sequenceCommandEnum_e Sequence_GetCommandEnumForName( const char *commandName, sequenceCommandType_e type ) -{ - int i; - - for( i = 0; i < ARRAYSIZE( g_sequenceCommandMappingTable ); i++ ) - { - const sequenceCommandMapping_s *mapping = g_sequenceCommandMappingTable + i; - - if( mapping->commandType == type && !Q_stricmp( mapping->commandName, commandName ) ) - return mapping->commandEnum; - } - return SEQUENCE_COMMAND_ERROR; -} - -/* -============= -Sequence_ResetDefaults - -============= -*/ -static void Sequence_ResetDefaults( sequenceCommandLine_s *destination, sequenceCommandLine_s *source ) -{ - if( !source ) - { - static client_textmessage_t defaultClientMessage = - { - 0, // effect - 255, 255, 255, 255, // rgba1 - 255, 255, 255, 255, // rgba2 - 0.5, 0.5, // xy - 0.2, 0.2, // fade-in/out - 1.6, // holdtime - 1.0, // fxtime - NULL, NULL // pName, pMessage - }; - - destination->clientMessage = defaultClientMessage; - destination->textChannel = 0; - destination->delay = 0; - destination->repeatCount = 0; - destination->nextCommandLine = NULL; - destination->soundFileName = NULL; - destination->speakerName = NULL; - destination->listenerName = NULL; - return; - } - - destination->clientMessage = source->clientMessage; - destination->clientMessage.pName = NULL; - destination->clientMessage.pMessage = NULL; - destination->textChannel = source->textChannel; - destination->delay = source->delay; - destination->repeatCount = source->repeatCount; - destination->nextCommandLine = NULL; - destination->soundFileName = NULL; - - Z_Free( destination->speakerName ); - destination->speakerName = copystring( source->speakerName ); - - Z_Free( destination->listenerName ); - destination->listenerName = copystring( source->listenerName ); -} - -/* -============= -Sequence_WriteDefaults - -============= -*/ -static void Sequence_WriteDefaults( sequenceCommandLine_s *source, sequenceCommandLine_s *destination ) -{ - if( !destination ) - Con_Reportf( S_ERROR "Attempt to bake defaults into a non-existant command." ); - - if( !source ) - Con_Reportf( S_ERROR "Attempt to bake defaults from a non-existant command." ); - - if( source->modifierBitField & SEQUENCE_MODIFIER_EFFECT_BIT ) - { - destination->clientMessage.effect = source->clientMessage.effect; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_POSITION_BIT ) - { - destination->clientMessage.x = source->clientMessage.x; - destination->clientMessage.y = source->clientMessage.y; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_COLOR_BIT ) - { - destination->clientMessage.r1 = source->clientMessage.r1; - destination->clientMessage.g1 = source->clientMessage.g1; - destination->clientMessage.b1 = source->clientMessage.b1; - destination->clientMessage.a1 = source->clientMessage.a1; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_COLOR2_BIT ) - { - destination->clientMessage.r2 = source->clientMessage.r2; - destination->clientMessage.g2 = source->clientMessage.g2; - destination->clientMessage.b2 = source->clientMessage.b2; - destination->clientMessage.a2 = source->clientMessage.a2; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_FADEIN_BIT ) - { - destination->clientMessage.fadein = source->clientMessage.fadein; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_FADEOUT_BIT ) - { - destination->clientMessage.fadeout = source->clientMessage.fadeout; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_HOLDTIME_BIT ) - { - destination->clientMessage.holdtime = source->clientMessage.holdtime; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_FXTIME_BIT ) - { - destination->clientMessage.fxtime = source->clientMessage.fxtime; - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_SPEAKER_BIT ) - { - Z_Free( destination->speakerName ); - destination->speakerName = copystring( source->speakerName ); - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_LISTENER_BIT ) - { - Z_Free( destination->listenerName ); - destination->listenerName = copystring( source->listenerName ); - } - - if( source->modifierBitField & SEQUENCE_MODIFIER_TEXTCHANNEL_BIT ) - { - destination->textChannel = source->textChannel; - } -} - -/* -============= -Sequence_BakeDefaults - -============= -*/ -static void Sequence_BakeDefaults( sequenceCommandLine_s *destination, sequenceCommandLine_s *source ) -{ - char *saveName, *saveMessage; - - if( !destination ) - Con_Reportf( S_ERROR "Attempt to bake defaults into a non-existant command." ); - - if( !source ) - Con_Reportf( S_ERROR "Attempt to bake defaults from a non-existant command." ); - - saveName= destination->clientMessage.pName; - saveMessage = destination->clientMessage.pMessage; - - destination->clientMessage = source->clientMessage; - - destination->clientMessage.pName = saveName; - destination->clientMessage.pMessage = saveMessage; - - destination->textChannel = source->textChannel; - - Z_Free( destination->speakerName ); - destination->speakerName = copystring( source->speakerName ); - - Z_Free( destination->listenerName ); - destination->listenerName = copystring( source->listenerName ); -} - -/* -============= -Sequence_SkipWhitespace - -============= -*/ -static qboolean Sequence_SkipWhitespace( void ) -{ - qboolean newLine = false; - - for( ; isspace( *g_scan ); g_scan++ ) - { - if( *g_scan == '\n' ) - { - g_lineScan = g_scan + 1; - g_lineNum++; - - newLine = true; - } - } - - return newLine; -} - -/* -============= -Sequence_IsNameValueChar - -============= -*/ -static qboolean Sequence_IsNameValueChar( char ch ) -{ - if( isalnum( ch ) ) - return true; - - switch( ch ) - { - case '.': - case '-': - case '_': - case '/': - case '\\': - return true; - } - - return false; -} - -/* -============= -Sequence_IsSymbol - -============= -*/ -static qboolean Sequence_IsSymbol( char ch ) -{ - switch( ch ) - { - case '"': - case '#': - case '$': - case '%': - case ',': - case '=': - case '@': - case '{': - case '}': - return true; - } - - return false; -} - -/* -============= -Sequence_GetNameValueString - -============= -*/ -static size_t Sequence_GetNameValueString( char *token, size_t len ) -{ - char *p; - - Sequence_SkipWhitespace( ); - - if( !Sequence_IsNameValueChar( *g_scan ) ) - { - if( *g_scan == '#' || *g_scan == '$' ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: cannot have more than one '%c' per line; '%c' must be at the beginning of the line ONLY\n", g_lineNum, g_sequenceParseFileName, *g_scan, *g_scan ); - else - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: expected name/value, found illegal character '%c'\n", g_lineNum, g_sequenceParseFileName, *g_scan ); - } - - for( p = token; Sequence_IsNameValueChar( *g_scan ) && len; p++, g_scan++, len-- ) - { - *p = *g_scan; - } - - *p = 0; - - return p - token; -} - -/* -============= -Sequence_GetSymbol - -============= -*/ -static char Sequence_GetSymbol( void ) -{ - char ch; - - Sequence_SkipWhitespace( ); - - ch = *g_scan; - - if( ch ) - g_scan++; - - return ch; -} - -/* -============= -Sequence_ValidateNameValueString - -============= -*/ -static void Sequence_ValidateNameValueString( char *token ) -{ - char *scan; - - for( scan = token; *scan; scan++ ) - { - if( !Sequence_IsNameValueChar( *scan ) ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: name/value string \"%s\" had illegal character '%c'\n", g_lineNum, g_sequenceParseFileName, token, *scan ); - } -} - -/* -============= -Sequence_GetToken - -============= -*/ -static size_t Sequence_GetToken( char *token, size_t size ) -{ - Sequence_SkipWhitespace( ); - - if( Sequence_IsNameValueChar( *g_scan ) ) - { - return Sequence_GetNameValueString( token, size ); - } - - if( !Sequence_IsSymbol( *g_scan ) ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: expected token, found '%c' instead\n", g_lineNum, g_sequenceParseFileName, *g_scan ); - - token[0] = *g_scan++; - token[1] = 0; - g_scan++; - - return 1; // only one symbol has copied to token -} - -/* -============= -Sequence_GetLine - -============= -*/ -static size_t Sequence_GetLine( char *line, int lineMaxLen ) -{ - int lineLen; - char *read; - char *write = line; - - Sequence_SkipWhitespace( ); - - read = Q_strchr( g_scan, '\n' ); - - if( !read ) - Con_Reportf( S_ERROR "Syntax Error on line %d of %s.seq: expected sentence definition or '}', found End-Of-File!\n", g_lineNum, g_sequenceParseFileName ); - - lineLen = read - g_scan; - - if( lineLen >= lineMaxLen ) - Con_Reportf( S_ERROR "Syntax Error on line %d of %s.seq: line was too long (was %d chars; max is %d chars)\n", g_lineNum, g_sequenceParseFileName, lineLen, lineMaxLen - 1 ); - - Q_strncpy( write, g_scan, lineLen ); - write[lineLen] = 0; - g_scan = read; - - return lineLen; -} - -/* -============= -Sequence_StripComments - -============= -*/ -static void Sequence_StripComments( char *buffer, int *pBufSize ) -{ - char *eof = buffer + *pBufSize; - char *read = buffer; - char *write = buffer; - - for( ; read < eof; ) - { - if( !*read ) - break; - - if( *read == '/' ) - { - // skip one line comments // - if( read[1] == '/' ) - { - read += 2; - - while( *read ) - { - if( *read == '\n' ) - break; - - if( *read == '\r' ) - break; - - read++; - } - - continue; - } - - // skip multiline /* */ - if( read[1] == '*' ) - { - read += 2; - - while( *read && read[1] ) - { - if( *read == '*' && read[1] == '/' ) - { - read += 2; - break; - } - - if( *read == '\n' || *read == '\r' ) - *write++ = *read; - - read++; - } - - continue; - } - } - - *write++ = *read++; - } - - *write = 0; -} - -/* -============= -Sequence_ReadInt - -============= -*/ -static int Sequence_ReadInt( void ) -{ - char str[MAX_STRING]; - - Sequence_SkipWhitespace( ); - Sequence_GetNameValueString( str, MAX_STRING ); - - return Q_atoi( str ); -} - -/* -============= -Sequence_ReadFloat - -============= -*/ -static float Sequence_ReadFloat( void ) -{ - char str[MAX_STRING]; - - Sequence_SkipWhitespace( ); - Sequence_GetNameValueString( str, MAX_STRING ); - - return Q_atof( str ); -} - -/* -============= -Sequence_ReadFloat - -============= -*/ -static void Sequence_ReadString( char **dest, char *string, size_t len ) -{ - Sequence_SkipWhitespace( ); - Sequence_GetNameValueString( string, len ); - - if( dest ) *dest = copystring( string ); -} - -/* -============= -Sequence_ReadQuotedString - -============= -*/ -static void Sequence_ReadQuotedString( char **dest, char *str, size_t len ) -{ - char *write, ch; - - Sequence_SkipWhitespace( ); - - ch = Sequence_GetSymbol( ); - if( ch != '\"' ) - Con_Reportf( S_ERROR "Parsing error on or before line %d of %s.seq: expected quote (\"), found '%c' instead\n", g_lineNum, g_sequenceParseFileName, ch ); - - for( write = str; *g_scan && len; write++, g_scan++, len-- ) - { - if( *g_scan == '\"' ) - break; - - if( *g_scan == '\n' ) - g_lineNum++; - - *write = *g_scan; - } - - *write = 0; - g_scan++; - - if( dest ) *dest = copystring( str ); -} - -/* -============= -Sequence_ConfirmCarriageReturnOrSymbol - -============= -*/ -static qboolean Sequence_ConfirmCarriageReturnOrSymbol( char symbol ) -{ - if( Sequence_SkipWhitespace( ) ) - return true; - return *g_scan == symbol; -} - - -/* -============= -Sequence_IsCommandAModifier - -============= -*/ -static qboolean Sequence_IsCommandAModifier( sequenceCommandEnum_e commandEnum ) -{ - int i; - - for( i = 0; i < ARRAYSIZE( g_sequenceCommandMappingTable ); i++ ) - { - if( g_sequenceCommandMappingTable[i].commandEnum == commandEnum ) - return ( g_sequenceCommandMappingTable[i].commandType == SEQUENCE_TYPE_MODIFIER ); - } - - Con_Reportf( S_ERROR "Internal error caused by line %d of %s.seq: unknown command enum = %d\n", g_lineNum, g_sequenceParseFileName, commandEnum ); - return false; -} - -/* -============= -Sequence_ReadCommandData - -============= -*/ -static void Sequence_ReadCommandData( sequenceCommandEnum_e commandEnum, sequenceCommandLine_s *defaults ) -{ - char temp[1024]; - - if( commandEnum >= SEQUENCE_MODIFIER_EFFECT && commandEnum <= SEQUENCE_MODIFIER_TEXTCHANNEL ) - defaults->modifierBitField |= BIT( SEQUENCE_MODIFIER_EFFECT - SEQUENCE_COMMAND_NOOP ); - - switch( commandEnum ) - { - case SEQUENCE_COMMAND_PAUSE: - defaults->delay = Sequence_ReadFloat( ); - break; - - case SEQUENCE_COMMAND_FIRETARGETS: - Sequence_ReadQuotedString( &defaults->fireTargetNames, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_KILLTARGETS: - Sequence_ReadQuotedString( &defaults->killTargetNames, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_TEXT: - Sequence_ReadQuotedString( &defaults->clientMessage.pMessage, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_SOUND: - Sequence_ReadString( &defaults->soundFileName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_GOSUB: - Sequence_ReadString( &defaults->clientMessage.pName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_SENTENCE: - Sequence_ReadString( &defaults->sentenceName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_COMMAND_REPEAT: - defaults->repeatCount = Sequence_ReadInt( ); - break; - - case SEQUENCE_MODIFIER_EFFECT: - defaults->clientMessage.effect = Sequence_ReadInt( ); - break; - - case SEQUENCE_MODIFIER_POSITION: - defaults->clientMessage.x = Sequence_ReadFloat( ); - defaults->clientMessage.y = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_COLOR: - defaults->clientMessage.r1 = Sequence_ReadInt( ); - defaults->clientMessage.g1 = Sequence_ReadInt( ); - defaults->clientMessage.b1 = Sequence_ReadInt( ); - defaults->clientMessage.a1 = 255; - break; - - case SEQUENCE_MODIFIER_COLOR2: - defaults->clientMessage.r2 = Sequence_ReadInt( ); - defaults->clientMessage.g2 = Sequence_ReadInt( ); - defaults->clientMessage.b2 = Sequence_ReadInt( ); - defaults->clientMessage.a2 = 255; - break; - - case SEQUENCE_MODIFIER_FADEIN: - defaults->clientMessage.fadein = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_FADEOUT: - defaults->clientMessage.fadeout = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_HOLDTIME: - defaults->clientMessage.holdtime = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_FXTIME: - defaults->clientMessage.fxtime = Sequence_ReadFloat( ); - break; - - case SEQUENCE_MODIFIER_SPEAKER: - Sequence_ReadString( &defaults->speakerName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_MODIFIER_LISTENER: - Sequence_ReadString( &defaults->listenerName, temp, sizeof( temp ) ); - break; - - case SEQUENCE_MODIFIER_TEXTCHANNEL: - defaults->textChannel = Sequence_ReadInt( ); - break; - - default: - Con_Reportf( S_ERROR "Internal error caused by line %d of %s.seq: unknown command enum = %d\n", g_lineNum, g_sequenceParseFileName, commandEnum ); - } -} - -/* -============= -Sequence_ParseModifier - -============= -*/ -static char Sequence_ParseModifier( sequenceCommandLine_s *defaults ) -{ - char modifierName[MAX_STRING]; - char delimiter; - sequenceCommandEnum_e modifierEnum; - - Sequence_GetNameValueString( modifierName, MAX_STRING ); - modifierEnum = Sequence_GetCommandEnumForName( modifierName, SEQUENCE_TYPE_MODIFIER ); - - if( modifierEnum == SEQUENCE_COMMAND_ERROR ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: unknown modifier \"%s\"\n", g_lineNum, g_sequenceParseFileName, modifierName ); - - if( !Sequence_IsCommandAModifier( modifierEnum ) ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: \"%s\" is a #command, not a $modifier\n", g_lineNum, g_sequenceParseFileName, modifierName ); - - delimiter = Sequence_GetSymbol( ); - - if( delimiter != '=' ) - Con_Reportf( S_ERROR "Parsing error on or after line %d of %s.seq: after modifier \"%s\", expected '=', found '%c'\n", g_lineNum, g_sequenceParseFileName, modifierName, delimiter ); - - Sequence_ReadCommandData( modifierEnum, defaults ); - - if( !Sequence_ConfirmCarriageReturnOrSymbol( ',' ) ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: after value(s) for modifier \"%s\", expected ',' or End-Of-Line; found '%c'\n", g_lineNum, g_sequenceParseFileName, modifierName, *g_scan ); - - return Sequence_GetSymbol( ); -} - -/* -============= -Sequence_AddCommandLineToEntry - -============= -*/ -static void Sequence_AddCommandLineToEntry( sequenceCommandLine_s *commandLine, sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *scan; - - if( entry->firstCommand ) - { - for( scan = entry->firstCommand; scan->nextCommandLine; scan = scan->nextCommandLine ); - scan->nextCommandLine = commandLine; - } - else entry->firstCommand = commandLine; - - commandLine->nextCommandLine = NULL; -} - -/* -============= -Sequence_ParseModifierLine - -============= -*/ -static char Sequence_ParseModifierLine( sequenceEntry_s *entry, sequenceCommandType_e modifierType ) -{ - sequenceCommandLine_s *newCommandLine; - char delimiter = ','; - - while( delimiter == ',' ) - { - switch( modifierType ) - { - case SEQUENCE_TYPE_COMMAND: - newCommandLine = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( newCommandLine, 0, sizeof( sequenceCommandLine_s ) ); - newCommandLine->commandType = SEQUENCE_COMMAND_MODIFIER; - Sequence_AddCommandLineToEntry( newCommandLine, entry ); - delimiter = Sequence_ParseModifier( newCommandLine ); - break; - - case SEQUENCE_TYPE_MODIFIER: - delimiter = Sequence_ParseModifier( &g_fileScopeDefaults ); - break; - } - } - - return delimiter; -} - -/* -============= -Sequence_ParseCommand - -============= -*/ -static char Sequence_ParseCommand( sequenceCommandLine_s *newCommandLine ) -{ - char commandName[MAX_STRING], ch; - sequenceCommandEnum_e commandEnum; - sequenceCommandLine_s *modifierCommandLine; - - Sequence_GetNameValueString( commandName, MAX_STRING ); - commandEnum = Sequence_GetCommandEnumForName( commandName, SEQUENCE_TYPE_COMMAND ); - - if( commandEnum == SEQUENCE_COMMAND_ERROR ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: unknown command \"%s\"\n", g_lineNum, g_sequenceParseFileName, commandName ); - - if( Sequence_IsCommandAModifier( commandEnum ) ) - { - modifierCommandLine = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( modifierCommandLine, 0, sizeof( sequenceCommandLine_s ) ); - modifierCommandLine->commandType = SEQUENCE_COMMAND_POSTMODIFIER; - - for( ; newCommandLine->nextCommandLine; newCommandLine = newCommandLine->nextCommandLine ); - - newCommandLine->nextCommandLine = modifierCommandLine; - newCommandLine = modifierCommandLine; - } - - ch = Sequence_GetSymbol( ); - if( ch != '=' ) - Con_Reportf( S_ERROR "Parsing error on or before line %d of %s.seq: after command \"%s\", expected '=', found '%c'\n", - g_lineNum, g_sequenceParseFileName, commandName, ch ); - - Sequence_ReadCommandData( commandEnum, newCommandLine ); - return Sequence_GetSymbol( ); -} - -/* -============= -Sequence_ParseCommandLine - -============= -*/ -static char Sequence_ParseCommandLine( sequenceEntry_s *entry ) -{ - char symbol; - sequenceCommandLine_s *newCommandLine; - - newCommandLine = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( newCommandLine, 0, sizeof( sequenceCommandLine_s ) ); - - Sequence_ResetDefaults( newCommandLine, &g_blockScopeDefaults ); - Sequence_AddCommandLineToEntry( newCommandLine, entry ); - - symbol = Sequence_ParseCommand( newCommandLine ); - - while( symbol == ',' ) - { - symbol = Sequence_ParseCommand( newCommandLine ); - } - - return symbol; -} - -/* -============= -Sequence_ParseMacro - -============= -*/ -static char Sequence_ParseMacro( sequenceEntry_s *entry ) -{ - char symbol; - sequenceCommandLine_s *newCommandLine; - - newCommandLine = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( newCommandLine, 0, sizeof( sequenceCommandLine_s ) ); - - Sequence_ResetDefaults( newCommandLine, &g_blockScopeDefaults ); - Sequence_AddCommandLineToEntry( newCommandLine, entry ); - Sequence_ReadCommandData( SEQUENCE_COMMAND_GOSUB, newCommandLine ); - - symbol = Sequence_GetSymbol( ); - - while( symbol == ',' ) - { - symbol = Sequence_ParseCommand( newCommandLine ); - } - - return symbol; -} - -/* -============= -Sequence_ParseLine - -============= -*/ -static char Sequence_ParseLine( char start, sequenceEntry_s *entry ) -{ - char end = '\0'; - - switch( start ) - { - case '#': - end = Sequence_ParseCommandLine( entry ); - break; - - case '$': - end = Sequence_ParseModifierLine( entry, SEQUENCE_TYPE_MODIFIER ); - break; - - case '@': - end = Sequence_ParseMacro( entry ); - break; - - default: - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: line must begin with either '#' (command) or '$' (modifier); found '%c'\n", g_lineNum, g_sequenceParseFileName, start ); - } - - return end; -} - -/* -============= -Sequence_CalcEntryDuration - -============= -*/ -static float Sequence_CalcEntryDuration( sequenceEntry_s *entry ) -{ - float duration; - sequenceCommandLine_s *cmd; - - duration = 0; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - duration += cmd->delay; - - return duration; -} - -/* -============= -Sequence_DoesEntryContainInfiniteLoop - -============= -*/ -static qboolean Sequence_DoesEntryContainInfiniteLoop( sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *cmd; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - { - if( cmd->repeatCount < 0 ) - return true; - } - - return false; -} - -/* -============= -Sequence_IsEntrySafe - -============= -*/ -static qboolean Sequence_IsEntrySafe( sequenceEntry_s *entry ) -{ - float duration; - sequenceCommandLine_s *cmd; - - duration = 0; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - { - duration += cmd->delay; - - if( cmd->repeatCount < 0 ) - { - if( duration <= 0 ) - return false; - } - } - - return true; -} - -/* -============= -Sequence_CreateDefaultsCommand - -============= -*/ -static void Sequence_CreateDefaultsCommand( sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *cmd; - - cmd = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - memset( cmd, 0, sizeof( sequenceCommandLine_s ) ); - - Sequence_ResetDefaults( cmd, &g_fileScopeDefaults ); - cmd->commandType = SEQUENCE_COMMAND_SETDEFAULTS; - cmd->modifierBitField = SEQUENCE_MODIFIER_EFFECT_BIT | - SEQUENCE_MODIFIER_POSITION_BIT | - SEQUENCE_MODIFIER_COLOR_BIT | - SEQUENCE_MODIFIER_COLOR2_BIT | - SEQUENCE_MODIFIER_FADEIN_BIT | - SEQUENCE_MODIFIER_FADEOUT_BIT | - SEQUENCE_MODIFIER_HOLDTIME_BIT | - SEQUENCE_MODIFIER_FXTIME_BIT; - - Sequence_AddCommandLineToEntry( cmd, entry ); -} - - -/* -============= -Sequence_ParseEntry - -============= -*/ -static char Sequence_ParseEntry( void ) -{ - char symbol; - char token[MAX_STRING]; - sequenceEntry_s *entry; - - Sequence_GetNameValueString( token, MAX_STRING ); - symbol = Sequence_GetSymbol( ); - - if( symbol != '{' ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: expected '{' to start a\n new entry block; found '%c' instead!", g_lineNum, g_sequenceParseFileName, symbol ); - - entry = Z_Malloc( sizeof( sequenceEntry_s ) ); - Sequence_ResetDefaults( &g_blockScopeDefaults, &g_fileScopeDefaults ); - entry->entryName = copystring( token ); - entry->fileName = copystring( g_sequenceParseFileName ); - entry->isGlobal = g_sequenceParseFileIsGlobal; - entry->firstCommand = NULL; - Sequence_CreateDefaultsCommand( entry ); - - symbol = Sequence_GetSymbol( ); - - while( symbol != '}' ) - { - symbol = Sequence_ParseLine( symbol, entry ); - } - - if( !Sequence_IsEntrySafe( entry ) ) - Con_Reportf( S_ERROR "Logic error in file %s.seq before line %d: execution of entry \"%%%s\" would cause an infinite loop!", g_sequenceParseFileName, g_lineNum, entry->entryName ); - - entry->nextEntry = g_sequenceList; - g_sequenceList = entry; - - return Sequence_GetSymbol( ); -} - -/* -============= -Sequence_FindSentenceGroup - -============= -*/ -static sentenceGroupEntry_s *Sequence_FindSentenceGroup( const char *groupName ) -{ - sentenceGroupEntry_s *groupEntry; - - for( groupEntry = g_sentenceGroupList; groupEntry; groupEntry = groupEntry->nextEntry ) - { - if( !Q_stricmp( groupEntry->groupName, groupName ) ) - return groupEntry; - } - - return NULL; -} - -/* -============= -Sequence_GetSentenceByIndex - -============= -*/ -sentenceEntry_s *Sequence_GetSentenceByIndex( unsigned int index ) -{ - sentenceEntry_s *sentenceEntry; - sentenceGroupEntry_s *groupEntry; - unsigned int sentenceCount=0; - - for( groupEntry = g_sentenceGroupList; groupEntry; groupEntry = groupEntry->nextEntry ) - { - sentenceCount += groupEntry->numSentences; - - if( index < sentenceCount ) - { - for( sentenceEntry = groupEntry->firstSentence; sentenceEntry; sentenceEntry = sentenceEntry->nextEntry ) - { - if( sentenceEntry->index == index ) - return sentenceEntry; - } - } - } - - return NULL; -} - - -/* -============= -Sequence_PickSentence - -============= -*/ -sentenceEntry_s *Sequence_PickSentence( const char *groupName, int pickMethod, int *picked ) -{ - sentenceEntry_s *sentenceEntry; - sentenceGroupEntry_s *groupEntry; - unsigned int pickedIdx; - unsigned int entryIdx; - - groupEntry = Sequence_FindSentenceGroup( groupName ); - - if( groupEntry ) - { - pickedIdx = COM_RandomLong( 0, groupEntry->numSentences - 1 ); - sentenceEntry = groupEntry->firstSentence; - - for( entryIdx = pickedIdx; entryIdx; entryIdx-- ) - sentenceEntry = sentenceEntry->nextEntry; - } - else - { - pickedIdx = 0; - sentenceEntry = NULL; - } - - if( picked ) - *picked = pickedIdx; - - return sentenceEntry; -} - -/* -============= -Sequence_AddSentenceGroup - -============= -*/ -static sentenceGroupEntry_s *Sequence_AddSentenceGroup( char *groupName ) -{ - sentenceGroupEntry_s *entry, *last; - - entry = Z_Malloc( sizeof( sentenceGroupEntry_s ) ); - entry->numSentences = 0; - entry->firstSentence = NULL; - entry->nextEntry = NULL; - entry->groupName = copystring( groupName ); - - if( g_sentenceGroupList ) - { - for( last = g_sentenceGroupList; last->nextEntry; last = last->nextEntry ); - last->nextEntry = entry; - } - else - { - g_sentenceGroupList = entry; - } - - return entry; -} - -/* -============= -Sequence_AddSentenceToGroup - -============= -*/ -static void Sequence_AddSentenceToGroup( char *groupName, char *data ) -{ - sentenceEntry_s *entry, *last; - sentenceGroupEntry_s *group; - - group = Sequence_FindSentenceGroup( groupName ); - - if( !group ) - { - group = Sequence_AddSentenceGroup( groupName ); - - if( !group ) - Con_Reportf( S_ERROR "Unable to allocate sentence group %s at line %d in file %s.seq", groupName, g_lineNum, g_sequenceParseFileName ); - } - - entry = Z_Malloc( sizeof( sentenceEntry_s ) ); - entry->nextEntry = NULL; - entry->data = copystring( data ); - entry->index = g_nonGlobalSentences; - entry->isGlobal = g_sequenceParseFileIsGlobal; - - group->numSentences++; - g_nonGlobalSentences++; - - if( group->firstSentence ) - { - for( last = group->firstSentence; last->nextEntry; last = last->nextEntry ); - - last->nextEntry = entry; - } - else - { - group->firstSentence = entry; - } -} - -/* -============= -Sequence_ParseSentenceLine - -============= -*/ -static qboolean Sequence_ParseSentenceLine( void ) -{ - char data[1024]; - char fullgroup[64]; - char groupName[64]; - char *c; - int lastCharacterPos; - size_t len; - - len = Sequence_GetToken( fullgroup, sizeof( fullgroup ) ); - - if( *fullgroup == '}' ) - return true; - - c = fullgroup + len; - - while( !isalpha( *c ) && *c != '_' ) - c--; - - c += 1; - - if( *c ) - *c = 0; - - Q_strncpy( groupName, fullgroup, sizeof( groupName )); - - len = Sequence_GetLine( data, sizeof( data ) ); - lastCharacterPos = len - 1; - - if( data[lastCharacterPos] == '\n' || data[lastCharacterPos] == '\r' ) - data[lastCharacterPos] = 0; - - Sequence_AddSentenceToGroup( groupName, data ); - return false; -} - -/* -============== -Sequence_ParseSentenceBlock - -============== -*/ -static char Sequence_ParseSentenceBlock( void ) -{ - qboolean end = false; - char ch = Sequence_GetSymbol( ); - if( ch != '{' ) - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: expected '{' to start a\n new sentence block; found '%c' instead!", g_lineNum, g_sequenceParseFileName, ch ); - - while( !end ) - { - end = Sequence_ParseSentenceLine( ); - } - - return Sequence_GetSymbol( ); -} - -/* -============== -Sequence_ParseGlobalDataBlock - -============== -*/ -static char Sequence_ParseGlobalDataBlock( void ) -{ - char token[MAX_STRING]; - - Sequence_GetNameValueString( token, MAX_STRING ); - - if( Q_stricmp( token, "Sentences" ) ) - Con_Reportf( S_ERROR "Syntax error in file %s.seq on line %d: found global data block symbol '!' with unknown data type \"%s\"", g_sequenceParseFileName, g_lineNum, token ); - - return Sequence_ParseSentenceBlock( ); -} - -/* -============== -Sequence_GetEntryForName - -============== -*/ -static sequenceEntry_s *Sequence_GetEntryForName( const char *entryName ) -{ - sequenceEntry_s *scan; - - for( scan = g_sequenceList; scan; scan = scan->nextEntry ) - { - if( !Q_stricmp( entryName, scan->entryName ) ) - return scan; - } - - return NULL; -} - -/* -============== -Sequence_CopyCommand - -============== -*/ -static sequenceCommandLine_s *Sequence_CopyCommand( sequenceCommandLine_s *commandOrig ) -{ - sequenceCommandLine_s *commandCopy; - - commandCopy = Z_Malloc( sizeof( sequenceCommandLine_s ) ); - - commandCopy->commandType = commandOrig->commandType; - commandCopy->clientMessage = commandOrig->clientMessage; - commandCopy->clientMessage.pMessage = copystring( commandOrig->clientMessage.pMessage ); - commandCopy->clientMessage.pName = copystring( commandOrig->clientMessage.pName ); - commandCopy->speakerName = copystring( commandOrig->speakerName ); - commandCopy->listenerName = copystring( commandOrig->listenerName ); - commandCopy->soundFileName = copystring( commandOrig->soundFileName ); - commandCopy->sentenceName = copystring( commandOrig->sentenceName ); - commandCopy->fireTargetNames = copystring( commandOrig->fireTargetNames ); - commandCopy->killTargetNames = copystring( commandOrig->killTargetNames ); - commandCopy->delay = commandOrig->delay; - commandCopy->repeatCount = commandOrig->repeatCount; - commandCopy->textChannel = commandOrig->textChannel; - commandCopy->modifierBitField = commandOrig->modifierBitField; - commandCopy->nextCommandLine = NULL; - - return commandCopy; -} - -/* -============== -Sequence_CopyCommandList - -============== -*/ -static sequenceCommandLine_s *Sequence_CopyCommandList( sequenceCommandLine_s *list ) -{ - sequenceCommandLine_s *scan, *copy, *new, *prev; - - copy = NULL; - prev = NULL; - - for( scan = list; scan; scan = scan->nextCommandLine ) - { - if( scan->commandType != SEQUENCE_COMMAND_SETDEFAULTS ) - { - new = Sequence_CopyCommand( scan ); - - if( prev ) - { - prev->nextCommandLine = new; - prev = new; - } - else - { - prev = new; - copy = new; - } - } - } - - return copy; -} - -/* -============== -Sequence_ExpandGosubsForEntry - -============== -*/ -static qboolean Sequence_ExpandGosubsForEntry( sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *cmd, *copyList, *scan; - sequenceEntry_s *gosubEntry; - qboolean foundGosubs = false; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - { - if( !cmd->clientMessage.pName ) - continue; - - if( !Q_stricmp( cmd->clientMessage.pName, entry->entryName ) ) - Con_Reportf( S_ERROR "Error in %s.seq: entry \"%s\" gosubs itself!\n", entry->fileName, entry->entryName ); - - gosubEntry = Sequence_GetEntryForName( cmd->clientMessage.pName ); - - if( !gosubEntry ) - Con_Reportf( S_ERROR "Error in %s.seq: Gosub in entry \"%s\" specified unknown entry \"%s\"\n", entry->fileName, entry->entryName, cmd->clientMessage.pName ); - - foundGosubs = true; - copyList = Sequence_CopyCommandList( gosubEntry->firstCommand ); - - if( copyList ) - { - for( scan = copyList->nextCommandLine; scan; scan = scan->nextCommandLine ); - - scan->nextCommandLine = cmd->nextCommandLine; - - Z_Free( cmd->clientMessage.pName ); - cmd->clientMessage.pName = NULL; - cmd = scan; - } - else - { - Z_Free( cmd->clientMessage.pName ); - cmd->clientMessage.pName = NULL; - } - } - - return !foundGosubs; -} - -/* -============== -Sequence_ExpandAllGosubs - -============== -*/ -static void Sequence_ExpandAllGosubs( void ) -{ - sequenceEntry_s *scan; - qboolean isComplete = true; - - while( !isComplete ) - { - for( scan = g_sequenceList; scan; scan = scan->nextEntry ) - { - isComplete = Sequence_ExpandGosubsForEntry( scan ); - } - } -} - -/* -============== -Sequence_FlattenEntry - -============== -*/ -static void Sequence_FlattenEntry( sequenceEntry_s *entry ) -{ - sequenceCommandLine_s *cmd, *last = NULL; - - for( cmd = entry->firstCommand; cmd; cmd = cmd->nextCommandLine ) - { - switch( cmd->commandType ) - { - case SEQUENCE_COMMAND_SETDEFAULTS: - Sequence_WriteDefaults( cmd, &g_blockScopeDefaults ); - cmd->commandType = SEQUENCE_COMMAND_NOOP; - break; - - case SEQUENCE_COMMAND_MODIFIER: - Sequence_WriteDefaults( cmd, &g_blockScopeDefaults ); - break; - - case SEQUENCE_COMMAND_POSTMODIFIER: - Sequence_WriteDefaults( cmd, last ); - break; - - default: - Sequence_BakeDefaults( cmd, &g_blockScopeDefaults ); - last = cmd; - } - } -} - -/* -============== -Sequence_FlattenAllEntries - -============== -*/ -static void Sequence_FlattenAllEntries( void ) -{ - sequenceEntry_s *entry; - - for( entry = g_sequenceList; entry; entry = entry->nextEntry ) - Sequence_FlattenEntry( entry ); -} - -/* -============== -Sequence_ParseBuffer - -============== -*/ -static void Sequence_ParseBuffer( char *buffer, int bufferSize ) -{ - char symbol; - - g_lineNum = 1; - g_scan = buffer; - g_lineScan = g_scan; - - Sequence_StripComments( buffer, &bufferSize ); - Sequence_ResetDefaults( &g_fileScopeDefaults, NULL ); - - symbol = Sequence_GetSymbol( ); - - while( symbol ) - { - switch( symbol ) - { - case '$': - do - symbol = Sequence_ParseModifier( &g_fileScopeDefaults ); - while( symbol == ',' ); - break; - - case '%': - symbol = Sequence_ParseEntry( ); - break; - - case '!': - symbol = Sequence_ParseGlobalDataBlock( ); - break; - - default: - Con_Reportf( S_ERROR "Parsing error on line %d of %s.seq: At file scope, lines must begin with '$' (modifier) or '%%' (entry block) or '!' (sentence / global data block); found '%c'\n", g_lineNum, g_sequenceParseFileName, symbol ); - } - } - - Sequence_ExpandAllGosubs( ); - Sequence_FlattenAllEntries( ); -} - -/* -============== -Sequence_ParseFile - -============== -*/ -static void Sequence_ParseFile( const char *fileName, qboolean isGlobal ) -{ - byte *buffer; - fs_offset_t bufSize = 0; - - Q_strncpy( g_sequenceParseFileName, fileName, sizeof( g_sequenceParseFileName )); - g_sequenceParseFileIsGlobal = isGlobal; - - buffer = FS_LoadFile( va("sequences/%s.seq", fileName ), &bufSize, true ); - - if( !buffer ) - return; - - Con_Reportf( "reading sequence file: %s\n", fileName ); - - Sequence_ParseBuffer( (char *)buffer, bufSize ); - - Mem_Free( buffer ); -} - -/* -============== -Sequence_Init - -============== -*/ -void Sequence_Init( void ) -{ - Sequence_ParseFile( "global", true ); -} - -/* -============== -SequenceGet - -============== -*/ -sequenceEntry_s *Sequence_Get( const char *fileName, const char *entryName ) -{ - sequenceEntry_s *scan; - - for( scan = g_sequenceList; scan; scan = scan->nextEntry ) - { - if( ( !fileName || !Q_stricmp( fileName, scan->fileName ) ) && // a1ba: add filename check, even if originally it is ignored - !Q_stricmp( entryName, scan->entryName ) ) - return scan; - } - - return NULL; -} - -/* -============== -Sequence_FreeCommand - -============== -*/ -static void Sequence_FreeCommand( sequenceCommandLine_s *kill ) -{ - Z_Free( kill->fireTargetNames ); - Z_Free( kill->speakerName ); - Z_Free( kill->listenerName ); - Z_Free( kill->soundFileName ); - Z_Free( kill->sentenceName ); - Z_Free( kill->clientMessage.pName ); - Z_Free( kill->clientMessage.pMessage ); -} - -/* -============== -Sequence_FreeEntry - -============== -*/ -static void Sequence_FreeEntry( sequenceEntry_s *kill ) -{ - sequenceCommandLine_s *dead; - - Z_Free( kill->entryName ); - Z_Free( kill->fileName ); - - for( dead = kill->firstCommand; dead; dead = dead->nextCommandLine ) - { - kill->firstCommand = dead->nextCommandLine; - Sequence_FreeCommand( dead ); - } - - Z_Free( kill ); -} - -/* -============== -Sequence_FreeSentence - -============== -*/ -static void Sequence_FreeSentence( sentenceEntry_s *sentenceEntry ) -{ - Z_Free( sentenceEntry->data ); - Z_Free( sentenceEntry ); -} - -/* -============== -Sequence_FreeSentenceGroup - -============== -*/ -static void Sequence_FreeSentenceGroup( sentenceGroupEntry_s *groupEntry ) -{ - Z_Free( groupEntry->groupName ); - Z_Free( groupEntry ); -} - -/* -============== -Sequence_FreeSentenceGroupEntries - -============== -*/ -static void Sequence_FreeSentenceGroupEntries( sentenceGroupEntry_s *groupEntry, qboolean purgeGlobals ) -{ - sentenceEntry_s *sentenceEntry; - sentenceEntry_s *deadSentence; - sentenceEntry_s *prevSentence; - - sentenceEntry = groupEntry->firstSentence; - prevSentence = NULL; - - while( sentenceEntry ) - { - if( !sentenceEntry->isGlobal || purgeGlobals ) - { - if( prevSentence ) - prevSentence->nextEntry = sentenceEntry->nextEntry; - else - groupEntry->firstSentence = sentenceEntry->nextEntry; - - groupEntry->numSentences--; - g_nonGlobalSentences--; - - deadSentence = sentenceEntry; - sentenceEntry = sentenceEntry->nextEntry; - - Sequence_FreeSentence( deadSentence ); - } - else - { - prevSentence = sentenceEntry; - sentenceEntry = sentenceEntry->nextEntry; - } - } -} - -/* -============== -Sequence_PurgeEntries - -============== -*/ -static void Sequence_PurgeEntries( qboolean purgeGlobals ) -{ - sequenceEntry_s *scan; - sequenceEntry_s *dead; - sequenceEntry_s *prev; - sentenceGroupEntry_s *groupEntry; - sentenceGroupEntry_s *deadGroup; - sentenceGroupEntry_s *prevGroup; - - dead = NULL; - prev = NULL; - - for( scan = g_sequenceList; scan; ) - { - if( !scan->isGlobal || purgeGlobals ) - { - if( prev ) - prev->nextEntry = scan->nextEntry; - else - g_sequenceList = scan->nextEntry; - - dead = scan; - scan = scan->nextEntry; - Sequence_FreeEntry( dead ); - } - else - { - prev = scan; - scan = scan->nextEntry; - } - } - - groupEntry = g_sentenceGroupList; - prevGroup = NULL; - - while( groupEntry ) - { - Sequence_FreeSentenceGroupEntries( groupEntry, purgeGlobals ); - - if( groupEntry->numSentences ) - { - prevGroup = groupEntry; - groupEntry = groupEntry->nextEntry; - } - else - { - if( prevGroup ) - prevGroup->nextEntry = groupEntry->nextEntry; - else - g_sentenceGroupList = groupEntry->nextEntry; - - deadGroup = groupEntry; - groupEntry = groupEntry->nextEntry; - Sequence_FreeSentenceGroup( deadGroup ); - } - } -} - -/* -============== -Sequence_OnLevelLoad - -============== -*/ -void Sequence_OnLevelLoad( const char *mapName ) -{ - Sequence_PurgeEntries( false ); - Sequence_ParseFile( mapName, false ); -} diff --git a/engine/sequence.h b/engine/sequence.h deleted file mode 100644 index e7d8aabc..00000000 --- a/engine/sequence.h +++ /dev/null @@ -1,203 +0,0 @@ -//--------------------------------------------------------------------------- -// -// S c r i p t e d S e q u e n c e s -// -//--------------------------------------------------------------------------- -#ifndef _INCLUDE_SEQUENCE_H_ -#define _INCLUDE_SEQUENCE_H_ - - -#ifndef _DEF_BYTE_ -//typedef unsigned char byte; -#endif - -#ifndef CDLL_INT_H -//--------------------------------------------------------------------------- -// client_textmessage_t -//--------------------------------------------------------------------------- -typedef struct client_textmessage_s -{ - int effect; - byte r1, g1, b1, a1; // 2 colors for effects - byte r2, g2, b2, a2; - float x; - float y; - float fadein; - float fadeout; - float holdtime; - float fxtime; - char *pName; - char *pMessage; -} client_textmessage_t; -#endif - - -//--------------------------------------------------------------------------- -// sequenceCommandEnum_e -// -// Enumerated sequence command types. -//--------------------------------------------------------------------------- -enum sequenceCommandEnum_ -{ - SEQUENCE_COMMAND_ERROR = -1, - SEQUENCE_COMMAND_PAUSE = 0, - SEQUENCE_COMMAND_FIRETARGETS, - SEQUENCE_COMMAND_KILLTARGETS, - SEQUENCE_COMMAND_TEXT, - SEQUENCE_COMMAND_SOUND, - SEQUENCE_COMMAND_GOSUB, - SEQUENCE_COMMAND_SENTENCE, - SEQUENCE_COMMAND_REPEAT, - SEQUENCE_COMMAND_SETDEFAULTS, - SEQUENCE_COMMAND_MODIFIER, - SEQUENCE_COMMAND_POSTMODIFIER, - SEQUENCE_COMMAND_NOOP, - - SEQUENCE_MODIFIER_EFFECT, - SEQUENCE_MODIFIER_POSITION, - SEQUENCE_MODIFIER_COLOR, - SEQUENCE_MODIFIER_COLOR2, - SEQUENCE_MODIFIER_FADEIN, - SEQUENCE_MODIFIER_FADEOUT, - SEQUENCE_MODIFIER_HOLDTIME, - SEQUENCE_MODIFIER_FXTIME, - SEQUENCE_MODIFIER_SPEAKER, - SEQUENCE_MODIFIER_LISTENER, - SEQUENCE_MODIFIER_TEXTCHANNEL, -}; -typedef enum sequenceCommandEnum_ sequenceCommandEnum_e; - -//-------------------------------------------------------------------------- -// sequenceDefaultBits_e -// -// Enumerated list of possible modifiers for a command. This enumeration -// is used in a bitarray controlling what modifiers are specified for a command. -//--------------------------------------------------------------------------- -enum sequenceModifierBits -{ - SEQUENCE_MODIFIER_EFFECT_BIT = (1 << 1), - SEQUENCE_MODIFIER_POSITION_BIT = (1 << 2), - SEQUENCE_MODIFIER_COLOR_BIT = (1 << 3), - SEQUENCE_MODIFIER_COLOR2_BIT = (1 << 4), - SEQUENCE_MODIFIER_FADEIN_BIT = (1 << 5), - SEQUENCE_MODIFIER_FADEOUT_BIT = (1 << 6), - SEQUENCE_MODIFIER_HOLDTIME_BIT = (1 << 7), - SEQUENCE_MODIFIER_FXTIME_BIT = (1 << 8), - SEQUENCE_MODIFIER_SPEAKER_BIT = (1 << 9), - SEQUENCE_MODIFIER_LISTENER_BIT = (1 << 10), - SEQUENCE_MODIFIER_TEXTCHANNEL_BIT = (1 << 11), -}; -typedef enum sequenceModifierBits sequenceModifierBits_e ; - - -//--------------------------------------------------------------------------- -// sequenceCommandType_e -// -// Typeerated sequence command types. -//--------------------------------------------------------------------------- -enum sequenceCommandType_ -{ - SEQUENCE_TYPE_COMMAND, - SEQUENCE_TYPE_MODIFIER, -}; -typedef enum sequenceCommandType_ sequenceCommandType_e; - - -//--------------------------------------------------------------------------- -// sequenceCommandMapping_s -// -// A mapping of a command enumerated-value to its name. -//--------------------------------------------------------------------------- -typedef struct sequenceCommandMapping_ sequenceCommandMapping_s; -struct sequenceCommandMapping_ -{ - sequenceCommandEnum_e commandEnum; - const char* commandName; - sequenceCommandType_e commandType; -}; - - -//--------------------------------------------------------------------------- -// sequenceCommandLine_s -// -// Structure representing a single command (usually 1 line) from a -// .SEQ file entry. -//--------------------------------------------------------------------------- -typedef struct sequenceCommandLine_ sequenceCommandLine_s; -struct sequenceCommandLine_ -{ - int commandType; // Specifies the type of command - client_textmessage_t clientMessage; // Text HUD message struct - char* speakerName; // Targetname of speaking entity - char* listenerName; // Targetname of entity being spoken to - char* soundFileName; // Name of sound file to play - char* sentenceName; // Name of sentences.txt to play - char* fireTargetNames; // List of targetnames to fire - char* killTargetNames; // List of targetnames to remove - float delay; // Seconds 'till next command - int repeatCount; // If nonzero, reset execution pointer to top of block (N times, -1 = infinite) - int textChannel; // Display channel on which text message is sent - int modifierBitField; // Bit field to specify what clientmessage fields are valid - sequenceCommandLine_s* nextCommandLine; // Next command (linked list) -}; - - -//--------------------------------------------------------------------------- -// sequenceEntry_s -// -// Structure representing a single command (usually 1 line) from a -// .SEQ file entry. -//--------------------------------------------------------------------------- -typedef struct sequenceEntry_ sequenceEntry_s; -struct sequenceEntry_ -{ - char* fileName; // Name of sequence file without .SEQ extension - char* entryName; // Name of entry label in file - sequenceCommandLine_s* firstCommand; // Linked list of commands in entry - sequenceEntry_s* nextEntry; // Next loaded entry - qboolean isGlobal; // Is entry retained over level transitions? -}; - - - -//--------------------------------------------------------------------------- -// sentenceEntry_s -// Structure representing a single sentence of a group from a .SEQ -// file entry. Sentences are identical to entries in sentences.txt, but -// can be unique per level and are loaded/unloaded with the level. -//--------------------------------------------------------------------------- -typedef struct sentenceEntry_ sentenceEntry_s; -struct sentenceEntry_ -{ - char* data; // sentence data (ie "We have hostiles" ) - sentenceEntry_s* nextEntry; // Next loaded entry - qboolean isGlobal; // Is entry retained over level transitions? - unsigned int index; // this entry's position in the file. -}; - -//-------------------------------------------------------------------------- -// sentenceGroupEntry_s -// Structure representing a group of sentences found in a .SEQ file. -// A sentence group is defined by all sentences with the same name, ignoring -// the number at the end of the sentence name. Groups enable a sentence -// to be picked at random across a group. -//-------------------------------------------------------------------------- -typedef struct sentenceGroupEntry_ sentenceGroupEntry_s; -struct sentenceGroupEntry_ -{ - char* groupName; // name of the group (ie CT_ALERT ) - unsigned int numSentences; // number of sentences in group - sentenceEntry_s* firstSentence; // head of linked list of sentences in group - sentenceGroupEntry_s* nextEntry; // next loaded group -}; - -//--------------------------------------------------------------------------- -// Function declarations -//--------------------------------------------------------------------------- -sequenceEntry_s* Sequence_Get( const char* fileName, const char* entryName ); -void Sequence_OnLevelLoad( const char* mapName ); -sentenceEntry_s* Sequence_PickSentence( const char *groupName, int pickMethod, int *picked ); -void Sequence_Init( void ); -sentenceEntry_s *Sequence_GetSentenceByIndex( unsigned int index ); - -#endif // _INCLUDE_SEQUENCE_H_ diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index cc5a7679..b33d12b6 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -19,7 +19,6 @@ GNU General Public License for more details. #include "library.h" #include "voice.h" #include "pm_local.h" -#include "sequence.h" #if XASH_LOW_MEMORY != 2 int SV_UPDATE_BACKUP = SINGLEPLAYER_BACKUP; @@ -1086,8 +1085,6 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba SV_InitEdict( ent ); } - Sequence_OnLevelLoad( sv.name ); - // heartbeats will always be sent to the id master NET_MasterClear();