2007-01-15 12:09:25 -08:00
/*
This file is part of Warzone 2100.
Copyright ( C ) 1999 - 2004 Eidos Interactive
2011-02-25 09:45:27 -08:00
Copyright ( C ) 2005 - 2011 Warzone 2100 Project
2007-01-15 12:09:25 -08:00
Warzone 2100 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 2 of the License , or
( at your option ) any later version .
Warzone 2100 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 .
You should have received a copy of the GNU General Public License
along with Warzone 2100 ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
2007-06-28 10:47:08 -07:00
/*
* Event . c
*
* The event management system .
*/
2006-06-02 12:34:58 -07:00
# include "lib/framework/frame.h"
2008-03-16 05:39:08 -07:00
2007-06-28 10:47:08 -07:00
# include "event.h"
2008-03-16 05:39:08 -07:00
# include "script.h"
2007-06-28 10:47:08 -07:00
// array to store release functions
2008-05-12 05:39:16 -07:00
static VAL_CREATE_FUNC * asCreateFuncs = NULL ;
static VAL_RELEASE_FUNC * asReleaseFuncs = NULL ;
2007-03-15 16:17:09 -07:00
static UDWORD numFuncs ;
2007-06-28 10:47:08 -07:00
2008-05-12 05:39:16 -07:00
/** The list of currently active triggers */
ACTIVE_TRIGGER * psTrigList = NULL ;
2007-06-28 10:47:08 -07:00
2008-05-12 05:39:16 -07:00
/** The list of callback triggers */
ACTIVE_TRIGGER * psCallbackList = NULL ;
2007-06-28 10:47:08 -07:00
2008-05-12 05:39:16 -07:00
/** The new triggers added this loop */
static ACTIVE_TRIGGER * psAddedTriggers = NULL ;
2007-06-28 10:47:08 -07:00
2008-05-12 05:39:16 -07:00
/** The trigger which is currently firing */
static ACTIVE_TRIGGER * psFiringTrigger = NULL ;
static UDWORD updateTime ;
2007-06-28 10:47:08 -07:00
2008-05-12 05:39:16 -07:00
/** The currently allocated contexts */
SCRIPT_CONTEXT * psContList = NULL ;
2007-06-28 10:47:08 -07:00
// The current event trace level
static SDWORD eventTraceLevel = 3 ;
// print info on trigger
# ifdef DEBUG
# define DB_TRIGINF(psTrigger, level)\
if ( eventTraceLevel > = ( level ) ) \
eventPrintTriggerInfo ( psTrigger )
2008-10-16 07:22:29 -07:00
// Print out all the info available about a trigger
static void eventPrintTriggerInfo ( ACTIVE_TRIGGER * psTrigger )
{
SCRIPT_CODE * psCode = psTrigger - > psContext - > psCode ;
const char * pTrigLab , * pEventLab ;
// find the debug info for the trigger
pTrigLab = eventGetTriggerID ( psCode , psTrigger - > trigger ) ;
// find the debug info for the event
pEventLab = eventGetEventID ( psCode , psTrigger - > event ) ;
debug ( LOG_WARNING , " trigger %s at %d -> %s " , pTrigLab , psTrigger - > testTime , pEventLab ) ;
if ( psTrigger - > offset ! = 0 )
{
debug ( LOG_WARNING , " %d " , psTrigger - > offset ) ;
}
}
2007-06-28 10:47:08 -07:00
# else
# define DB_TRIGINF(psTrigger, level)
# endif
// event tracing printf
# ifdef DEBUG
# define DB_TRACE(x, level) \
if ( eventTraceLevel > = ( level ) ) \
2008-04-26 08:21:23 -07:00
debug ( LOG_SCRIPT , x )
2007-06-28 10:47:08 -07:00
# else
# define DB_TRACE(x,level)
# endif
// Initialise a trigger
2011-03-12 17:32:15 -08:00
static bool eventInitTrigger ( ACTIVE_TRIGGER * * ppsTrigger , SCRIPT_CONTEXT * psContext ,
2007-06-28 10:47:08 -07:00
UDWORD event , SDWORD trigger , UDWORD currTime ) ;
// Add a trigger to the list in order
static void eventAddTrigger ( ACTIVE_TRIGGER * psTrigger ) ;
// Free up a trigger
static void eventFreeTrigger ( ACTIVE_TRIGGER * psTrigger ) ;
2010-11-20 18:18:58 -08:00
// Remove triggers marked for deletion
static void eventPruneList ( ACTIVE_TRIGGER * * psList ) ;
static void eventPruneLists ( void )
{
eventPruneList ( & psTrigList ) ;
eventPruneList ( & psCallbackList ) ;
eventPruneList ( & psAddedTriggers ) ;
}
2007-06-28 10:47:08 -07:00
//resets the event timer - updateTime
void eventTimeReset ( UDWORD initTime )
{
updateTime = initTime ;
}
/* Initialise the event system */
2011-03-12 17:32:15 -08:00
bool eventInitialise ( )
2007-06-28 10:47:08 -07:00
{
psTrigList = NULL ;
psCallbackList = NULL ;
psContList = NULL ;
eventTraceLevel = 0 ;
asCreateFuncs = NULL ;
asReleaseFuncs = NULL ;
numFuncs = 0 ;
2006-11-16 06:30:29 -08:00
strcpy ( last_called_script_event , " <none> " ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// reset the event system
void eventReset ( void )
{
SDWORD count = 0 ;
// Free any active triggers and their context's
while ( psTrigList )
{
2008-03-21 09:52:10 -07:00
ACTIVE_TRIGGER * psCurr = psTrigList ;
2007-06-28 10:47:08 -07:00
psTrigList = psTrigList - > psNext ;
if ( ! psCurr - > psContext - > release )
{
count + = 1 ;
}
eventRemoveContext ( psCurr - > psContext ) ;
2007-06-04 13:46:30 -07:00
free ( psCurr ) ;
2007-06-28 10:47:08 -07:00
}
// Free any active callback triggers and their context's
while ( psCallbackList )
{
2008-03-21 09:52:10 -07:00
ACTIVE_TRIGGER * psCurr = psCallbackList ;
2007-06-28 10:47:08 -07:00
psCallbackList = psCallbackList - > psNext ;
if ( ! psCurr - > psContext - > release )
{
count + = 1 ;
}
eventRemoveContext ( psCurr - > psContext ) ;
2007-06-04 13:46:30 -07:00
free ( psCurr ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-21 09:52:10 -07:00
// Now free any contexts that are left
2007-06-28 10:47:08 -07:00
while ( psContList )
{
if ( ! psContList - > release )
{
count + = 1 ;
}
eventRemoveContext ( psContList ) ;
}
2008-03-21 09:52:10 -07:00
if ( count > 0 )
2007-06-28 10:47:08 -07:00
{
2008-04-26 08:21:23 -07:00
debug ( LOG_SCRIPT , " eventReset: %d contexts still allocated at reset " , count ) ;
2007-06-28 10:47:08 -07:00
}
}
// Shutdown the event system
void eventShutDown ( void )
{
eventReset ( ) ;
if ( asCreateFuncs )
{
2007-04-15 03:43:05 -07:00
free ( asCreateFuncs ) ;
2007-06-12 10:56:34 -07:00
asCreateFuncs = NULL ;
2007-06-28 10:47:08 -07:00
}
if ( asReleaseFuncs )
{
2007-04-15 03:43:05 -07:00
free ( asReleaseFuncs ) ;
2007-06-12 10:56:34 -07:00
asReleaseFuncs = NULL ;
2007-06-28 10:47:08 -07:00
}
}
// get the trigger id string
2006-11-03 13:35:50 -08:00
const char * eventGetTriggerID ( SCRIPT_CODE * psCode , SDWORD trigger )
2007-06-28 10:47:08 -07:00
{
2006-11-03 13:35:50 -08:00
const char * pID , * pTrigType ;
static char aIDNum [ 255 ] ;
2007-06-28 10:47:08 -07:00
SDWORD i ;
TRIGGER_TYPE type ;
if ( ( trigger > = 0 ) & & ( trigger < psCode - > numTriggers ) )
{
type = psCode - > psTriggerData [ trigger ] . type ;
}
else
{
return " INACTIVE " ;
}
pTrigType = " UNKNOWN " ;
switch ( type )
{
case TR_INIT :
pTrigType = " INIT " ;
break ;
case TR_CODE :
pTrigType = " CODE " ;
break ;
case TR_WAIT :
pTrigType = " WAIT " ;
break ;
case TR_EVERY :
pTrigType = " EVERY " ;
break ;
case TR_PAUSE :
pTrigType = " PAUSE " ;
break ;
default :
if ( asScrCallbackTab )
{
pTrigType = asScrCallbackTab [ type - TR_CALLBACKSTART ] . pIdent ;
}
break ;
}
if ( psCode - > psDebug = = NULL | | type ! = TR_CODE )
{
2007-10-24 14:11:29 -07:00
snprintf ( aIDNum , sizeof ( aIDNum ) , " %d (%s) " , trigger , pTrigType ) ;
2007-06-28 10:47:08 -07:00
}
else
{
pID = " NOT FOUND " ;
for ( i = 0 ; i < psCode - > debugEntries ; i + + )
{
if ( psCode - > psDebug [ i ] . offset = = psCode - > pTriggerTab [ trigger ] )
{
pID = psCode - > psDebug [ i ] . pLabel ;
break ;
}
}
2007-10-24 14:11:29 -07:00
snprintf ( aIDNum , sizeof ( aIDNum ) , " %s (%s) " , pID , pTrigType ) ;
2007-06-28 10:47:08 -07:00
}
return aIDNum ;
}
// get the event id string
2006-11-03 13:35:50 -08:00
const char * eventGetEventID ( SCRIPT_CODE * psCode , SDWORD event )
2007-06-28 10:47:08 -07:00
{
2006-11-03 13:35:50 -08:00
const char * pID ;
static char aIDNum [ 255 ] ;
2007-06-28 10:47:08 -07:00
SDWORD i ;
2008-03-22 10:42:07 -07:00
// skip if not debugging scripts
if ( ! debugPartEnabled ( LOG_SCRIPT ) )
{
pID = " N/A " ;
return pID ;
}
2007-06-28 10:47:08 -07:00
if ( ( psCode - > psDebug = = NULL ) | |
( event < 0 ) | | ( event > psCode - > numEvents ) )
{
2007-10-24 14:11:29 -07:00
snprintf ( aIDNum , sizeof ( aIDNum ) , " %d " , event ) ;
2007-06-28 10:47:08 -07:00
return aIDNum ;
}
pID = " NOT FOUND " ;
for ( i = 0 ; i < psCode - > debugEntries ; i + + )
{
if ( psCode - > psDebug [ i ] . offset = = psCode - > pEventTab [ event ] )
{
pID = psCode - > psDebug [ i ] . pLabel ;
break ;
}
}
return pID ;
}
// Initialise the create/release function array - specify the maximum value type
2011-03-12 17:32:15 -08:00
bool eventInitValueFuncs ( SDWORD maxType )
2007-06-28 10:47:08 -07:00
{
2008-03-21 09:52:10 -07:00
ASSERT ( asReleaseFuncs = = NULL , " eventInitValueFuncs: array already initialised " ) ;
2007-06-28 10:47:08 -07:00
2010-12-05 08:25:43 -08:00
asCreateFuncs = ( VAL_CREATE_FUNC * ) calloc ( maxType , sizeof ( * asCreateFuncs ) ) ;
2007-06-28 10:47:08 -07:00
if ( ! asCreateFuncs )
{
2008-04-26 08:21:23 -07:00
debug ( LOG_SCRIPT , " eventInitValueFuncs: Out of memory " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2010-12-05 08:25:43 -08:00
asReleaseFuncs = ( VAL_RELEASE_FUNC * ) calloc ( maxType , sizeof ( * asReleaseFuncs ) ) ;
2007-06-28 10:47:08 -07:00
if ( ! asReleaseFuncs )
{
2008-04-26 08:21:23 -07:00
debug ( LOG_SCRIPT , " eventInitValueFuncs: Out of memory " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
numFuncs = maxType ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Add a new value create function
2011-03-12 17:32:15 -08:00
bool eventAddValueCreate ( INTERP_TYPE type , VAL_CREATE_FUNC create )
2007-06-28 10:47:08 -07:00
{
if ( type > = numFuncs )
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventAddValueCreate: type out of range " ) ;
return false ;
2007-06-28 10:47:08 -07:00
}
asCreateFuncs [ type ] = create ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Add a new value release function
2011-03-12 17:32:15 -08:00
bool eventAddValueRelease ( INTERP_TYPE type , VAL_RELEASE_FUNC release )
2007-06-28 10:47:08 -07:00
{
if ( type > = numFuncs )
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventAddValueRelease: type out of range " ) ;
return false ;
2007-06-28 10:47:08 -07:00
}
asReleaseFuncs [ type ] = release ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Create a new context for a script
2011-03-12 17:32:15 -08:00
bool eventNewContext ( SCRIPT_CODE * psCode , CONTEXT_RELEASE release ,
2007-06-28 10:47:08 -07:00
SCRIPT_CONTEXT * * ppsContext )
{
SCRIPT_CONTEXT * psContext ;
2008-03-27 11:38:25 -07:00
SDWORD val , storeIndex , arrayNum , arraySize ;
UDWORD i , j ;
INTERP_TYPE type ;
2007-06-28 10:47:08 -07:00
VAL_CHUNK * psNewChunk , * psNextChunk ;
2008-03-21 09:52:10 -07:00
ASSERT ( psCode ! = NULL , " eventNewContext: Invalid code pointer " ) ;
2007-06-28 10:47:08 -07:00
// Get a new context
2010-12-05 08:25:43 -08:00
psContext = ( SCRIPT_CONTEXT * ) calloc ( 1 , sizeof ( * psContext ) ) ;
2007-06-04 13:46:30 -07:00
if ( psContext = = NULL )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventNewContext: Out of memory " ) ;
return false ;
2007-06-28 10:47:08 -07:00
}
// Initialise the context
psContext - > psCode = psCode ;
psContext - > triggerCount = 0 ;
2006-09-17 13:39:25 -07:00
psContext - > release = release ;
2007-06-28 10:47:08 -07:00
psContext - > psGlobals = NULL ;
psContext - > id = - 1 ; // only used by the save game
val = psCode - > numGlobals + psCode - > arraySize - 1 ;
arrayNum = psCode - > numArrays - 1 ;
2008-03-27 11:38:25 -07:00
arraySize = 1 ;
2007-06-28 10:47:08 -07:00
if ( psCode - > numArrays > 0 )
{
2008-03-27 11:38:25 -07:00
for ( i = 0 ; i < psCode - > psArrayInfo [ arrayNum ] . dimensions ; i + + )
2007-06-28 10:47:08 -07:00
{
arraySize * = psCode - > psArrayInfo [ arrayNum ] . elements [ i ] ;
}
}
2006-08-15 11:38:51 -07:00
//prepare local variables (initialize, store type)
//-------------------------------
2008-03-27 11:38:25 -07:00
psCode - > ppsLocalVarVal = ( INTERP_VAL * * ) malloc ( sizeof ( INTERP_VAL * ) * psCode - > numEvents ) ; //allocate space for array of local var arrays for each event
2009-08-30 14:43:00 -07:00
//debug(LOG_SCRIPT,"allocated space for %d events", psCode->numEvents);
2008-03-27 11:38:25 -07:00
for ( i = 0 ; i < psCode - > numEvents ; i + + )
2006-08-15 11:38:51 -07:00
{
if ( psCode - > numLocalVars [ i ] > 0 ) //this event has any local vars declared
{
2008-03-27 11:38:25 -07:00
psCode - > ppsLocalVarVal [ i ] = ( INTERP_VAL * ) malloc ( sizeof ( INTERP_VAL ) * psCode - > numLocalVars [ i ] ) ; //allocate space for local vars array (for the current event)
2008-03-25 18:54:27 -07:00
2009-08-30 14:43:00 -07:00
//debug(LOG_SCRIPT,"Event %d has %d local variables", i, psCode->numLocalVars[i]);
2006-08-15 11:38:51 -07:00
2008-03-27 11:38:25 -07:00
for ( j = 0 ; j < psCode - > numLocalVars [ i ] ; j + + )
2006-08-15 11:38:51 -07:00
{
2008-03-27 11:38:25 -07:00
type = psCode - > ppsLocalVars [ i ] [ j ] ;
2006-08-15 11:38:51 -07:00
2008-03-27 11:38:25 -07:00
//debug(LOG_SCRIPT,"var %d's type: %d", i, type);
/* initialize Strings, integers, floats etc
memset to 0 , the only special case is strings */
memset ( & ( psCode - > ppsLocalVarVal [ i ] [ j ] ) , 0 , sizeof ( INTERP_VAL ) ) ;
if ( type = = VAL_STRING ) {
psCode - > ppsLocalVarVal [ i ] [ j ] . v . sval = ( char * ) malloc ( MAXSTRLEN ) ;
strcpy ( psCode - > ppsLocalVarVal [ i ] [ j ] . v . sval , " \0 " ) ;
2006-08-15 11:38:51 -07:00
}
//Initialize objects
if ( asCreateFuncs ! = NULL & & type < numFuncs & & asCreateFuncs [ type ] )
{
2008-03-27 11:38:25 -07:00
if ( ! asCreateFuncs [ type ] ( & ( psCode - > ppsLocalVarVal [ i ] [ j ] ) ) )
2006-08-15 11:38:51 -07:00
{
debug ( LOG_ERROR , " eventNewContext: asCreateFuncs failed for local var " ) ;
2011-01-17 15:36:49 -08:00
free ( psContext ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-15 11:38:51 -07:00
}
}
2008-03-27 11:38:25 -07:00
psCode - > ppsLocalVarVal [ i ] [ j ] . type = type ; //store (copy) var type (data used during parsing -> data used during interpreting)
//debug(LOG_SCRIPT, "i=%d, j=%d, value=%d",i,j,psCode->ppsLocalVarVal[i][j].v.ival);
2006-08-15 11:38:51 -07:00
}
2008-03-27 11:38:25 -07:00
//debug(LOG_SCRIPT,"------");
2006-08-15 11:38:51 -07:00
}
else //this event has no local vars
{
2008-03-27 11:38:25 -07:00
psCode - > ppsLocalVarVal [ i ] = NULL ;
2006-08-15 11:38:51 -07:00
}
2008-03-27 11:38:25 -07:00
2006-08-15 11:38:51 -07:00
}
2007-06-28 10:47:08 -07:00
while ( val > = 0 )
{
2010-12-05 08:25:43 -08:00
psNewChunk = ( VAL_CHUNK * ) malloc ( sizeof ( VAL_CHUNK ) ) ;
2007-06-04 13:46:30 -07:00
if ( psNewChunk = = NULL )
2007-06-28 10:47:08 -07:00
{
for ( psNewChunk = psContext - > psGlobals ; psNewChunk ; psNewChunk = psNextChunk )
{
psNextChunk = psNewChunk - > psNext ;
2007-06-04 13:46:30 -07:00
free ( psNewChunk ) ;
2007-06-28 10:47:08 -07:00
}
2007-06-04 13:46:30 -07:00
free ( psContext ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// Set the value types
storeIndex = val % CONTEXT_VALS ;
while ( storeIndex > = 0 )
{
if ( val > = psCode - > numGlobals )
{
type = psCode - > psArrayInfo [ arrayNum ] . type ;
}
else
{
type = psCode - > pGlobals [ val ] ;
}
2006-08-19 06:26:11 -07:00
2006-11-24 17:26:05 -08:00
// initialize Strings, integers etc
2008-03-27 11:38:25 -07:00
// memset to 0
memset ( & ( psNewChunk - > asVals [ storeIndex ] ) , 0 , sizeof ( INTERP_VAL ) ) ;
if ( type = = VAL_STRING ) {
psNewChunk - > asVals [ storeIndex ] . v . sval = ( char * ) malloc ( MAXSTRLEN ) ;
strcpy ( psNewChunk - > asVals [ storeIndex ] . v . sval , " \0 " ) ;
2006-08-19 06:26:11 -07:00
}
2008-03-27 11:38:25 -07:00
// set type
psNewChunk - > asVals [ storeIndex ] . type = type ;
2006-08-21 02:34:42 -07:00
//initialize objects
2007-06-28 10:47:08 -07:00
if ( asCreateFuncs ! = NULL & & type < numFuncs & & asCreateFuncs [ type ] )
{
if ( ! asCreateFuncs [ type ] ( psNewChunk - > asVals + storeIndex ) )
{
2007-06-04 13:46:30 -07:00
free ( psNewChunk ) ;
2007-06-28 10:47:08 -07:00
for ( psNewChunk = psContext - > psGlobals ; psNewChunk ; psNewChunk = psNextChunk )
{
psNextChunk = psNewChunk - > psNext ;
2007-06-04 13:46:30 -07:00
free ( psNewChunk ) ;
2007-06-28 10:47:08 -07:00
}
2007-06-04 13:46:30 -07:00
free ( psContext ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
}
storeIndex - = 1 ;
val - = 1 ;
arraySize - = 1 ;
if ( arraySize < = 0 )
{
// finished this array
arrayNum - = 1 ;
if ( arrayNum > = 0 )
{
// calculate the next array size
arraySize = 1 ;
for ( i = 0 ; i < psCode - > psArrayInfo [ arrayNum ] . dimensions ; i + + )
{
arraySize * = psCode - > psArrayInfo [ arrayNum ] . elements [ i ] ;
}
}
}
}
psNewChunk - > psNext = psContext - > psGlobals ;
psContext - > psGlobals = psNewChunk ;
}
psContext - > psNext = psContList ;
psContList = psContext ;
* ppsContext = psContext ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Copy a context, including variable values
2011-03-12 17:32:15 -08:00
bool eventCopyContext ( SCRIPT_CONTEXT * psContext , SCRIPT_CONTEXT * * ppsNew )
2007-06-28 10:47:08 -07:00
{
SCRIPT_CONTEXT * psNew ;
SDWORD val ;
VAL_CHUNK * psChunk , * psOChunk ;
2007-04-03 06:20:41 -07:00
ASSERT ( psContext ,
2006-08-23 05:58:48 -07:00
" eventCopyContext: Invalid context pointer " ) ;
2007-06-28 10:47:08 -07:00
// Get a new context
if ( ! eventNewContext ( psContext - > psCode , psContext - > release , & psNew ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// Now copy the values over
psChunk = psNew - > psGlobals ;
psOChunk = psContext - > psGlobals ;
while ( psChunk )
{
for ( val = 0 ; val < CONTEXT_VALS ; val + + )
{
psChunk - > asVals [ val ] . v . ival = psOChunk - > asVals [ val ] . v . ival ;
}
psChunk = psChunk - > psNext ;
psOChunk = psOChunk - > psNext ;
}
* ppsNew = psNew ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Add a new object to the trigger system
// Time is the application time at which all the triggers are to be started
2011-03-12 17:32:15 -08:00
bool eventRunContext ( SCRIPT_CONTEXT * psContext , UDWORD time )
2007-06-28 10:47:08 -07:00
{
SDWORD event ;
ACTIVE_TRIGGER * psTrigger ;
TRIGGER_DATA * psData ;
SCRIPT_CODE * psCode ;
2007-04-03 06:20:41 -07:00
ASSERT ( psContext ! = NULL ,
2006-08-23 05:58:48 -07:00
" eventNewObject: Invalid context pointer " ) ;
2007-06-28 10:47:08 -07:00
// Now setup all the triggers
psContext - > triggerCount = 0 ;
psCode = psContext - > psCode ;
for ( event = 0 ; event < psCode - > numEvents ; event + + )
{
if ( psCode - > pEventLinks [ event ] > = 0 )
{
// See if this is an init event
psData = psCode - > psTriggerData + psCode - > pEventLinks [ event ] ;
if ( psData - > type = = TR_INIT )
{
if ( ! interpRunScript ( psContext , IRT_EVENT , event , 0 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
}
else
{
if ( ! eventInitTrigger ( & psTrigger , psContext , event ,
psCode - > pEventLinks [ event ] , time ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
eventAddTrigger ( psTrigger ) ;
DB_TRACE ( ( " added " ) , 2 ) ;
DB_TRIGINF ( psTrigger , 2 ) ;
}
}
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Remove an object from the event system
void eventRemoveContext ( SCRIPT_CONTEXT * psContext )
{
2008-05-12 05:33:38 -07:00
ACTIVE_TRIGGER * psCurr , * psPrev , * psNext ;
2007-06-28 10:47:08 -07:00
VAL_CHUNK * psCChunk , * psNChunk ;
SCRIPT_CONTEXT * psCCont , * psPCont = NULL ;
SDWORD i , chunkStart ;
INTERP_VAL * psVal ;
// Get rid of all it's triggers
while ( psTrigList & & psTrigList - > psContext = = psContext )
{
psNext = psTrigList - > psNext ;
eventFreeTrigger ( psTrigList ) ;
psTrigList = psNext ;
}
2008-05-12 05:33:38 -07:00
for ( psPrev = NULL , psCurr = psTrigList ; psCurr ; psCurr = psNext )
2007-06-28 10:47:08 -07:00
{
psNext = psCurr - > psNext ;
if ( psCurr - > psContext = = psContext )
{
eventFreeTrigger ( psCurr ) ;
2008-05-12 05:33:38 -07:00
if ( psPrev )
{
psPrev - > psNext = psNext ;
}
2007-06-28 10:47:08 -07:00
}
else
{
psPrev = psCurr ;
}
}
// Get rid of all it's callback triggers
while ( psCallbackList & & psCallbackList - > psContext = = psContext )
{
psNext = psCallbackList - > psNext ;
eventFreeTrigger ( psCallbackList ) ;
psCallbackList = psNext ;
}
2008-05-12 05:33:38 -07:00
for ( psPrev = NULL , psCurr = psCallbackList ; psCurr ; psCurr = psNext )
2007-06-28 10:47:08 -07:00
{
psNext = psCurr - > psNext ;
if ( psCurr - > psContext = = psContext )
{
eventFreeTrigger ( psCurr ) ;
2008-05-12 05:33:38 -07:00
if ( psPrev )
{
psPrev - > psNext = psNext ;
}
2007-06-28 10:47:08 -07:00
}
else
{
psPrev = psCurr ;
}
}
// Call the release function for all the values
if ( asReleaseFuncs ! = NULL )
{
psCChunk = psContext - > psGlobals ;
chunkStart = 0 ;
for ( i = 0 ; i < psContext - > psCode - > numGlobals ; i + + )
{
if ( i - chunkStart > = CONTEXT_VALS )
{
chunkStart + = CONTEXT_VALS ;
psCChunk = psCChunk - > psNext ;
2006-08-23 05:58:48 -07:00
ASSERT ( psCChunk ! = NULL ,
" eventRemoveContext: not enough value chunks " ) ;
2007-06-28 10:47:08 -07:00
}
psVal = psCChunk - > asVals + ( i - chunkStart ) ;
if ( psVal - > type < numFuncs & & asReleaseFuncs [ psVal - > type ] ! = NULL )
{
asReleaseFuncs [ psVal - > type ] ( psVal ) ;
}
}
}
// Free it's variables
for ( psCChunk = psContext - > psGlobals ; psCChunk ; psCChunk = psNChunk )
{
psNChunk = psCChunk - > psNext ;
2008-06-16 13:38:26 -07:00
// FIXME FIXME FIXME - this is commented away because it made loading
// different savegames many times crash for inexplicable reasons. It
// will probably leak memory, though!
/* for(i=0;i < CONTEXT_VALS ; i++)
2008-05-11 03:34:48 -07:00
{
2008-05-24 06:58:26 -07:00
if ( psCChunk - > asVals [ i ] . type = = VAL_STRING & & psCChunk - > asVals [ i ] . v . sval )
{
2008-05-11 03:34:48 -07:00
free ( psCChunk - > asVals [ i ] . v . sval ) ;
2008-05-24 06:58:26 -07:00
psCChunk - > asVals [ i ] . v . sval = NULL ;
}
2008-06-16 13:38:26 -07:00
} */
2007-06-04 13:46:30 -07:00
free ( psCChunk ) ;
2007-06-28 10:47:08 -07:00
}
2008-05-24 06:58:26 -07:00
psContext - > psGlobals = NULL ;
2007-06-28 10:47:08 -07:00
// Remove it from the context list
if ( psContext = = psContList )
{
psCCont = psContList ;
psContList = psContList - > psNext ;
2007-06-04 13:46:30 -07:00
free ( psCCont ) ;
2007-06-28 10:47:08 -07:00
}
else
{
for ( psCCont = psContList ; psCCont & & psCCont ! = psContext ;
psCCont = psCCont - > psNext )
{
psPCont = psCCont ;
}
if ( psCCont )
{
psPCont - > psNext = psCCont - > psNext ;
2007-06-04 13:46:30 -07:00
free ( psContext ) ;
2007-06-28 10:47:08 -07:00
}
else
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventRemoveContext: context not found " ) ;
2007-06-28 10:47:08 -07:00
}
}
}
// Get the value pointer for a variable index
2011-03-12 17:32:15 -08:00
bool eventGetContextVal ( SCRIPT_CONTEXT * psContext , UDWORD index , INTERP_VAL * * ppsVal )
2007-06-28 10:47:08 -07:00
{
VAL_CHUNK * psChunk ;
// Find the chunk for the variable
psChunk = psContext - > psGlobals ;
while ( psChunk & & index > = CONTEXT_VALS )
{
index - = CONTEXT_VALS ;
psChunk = psChunk - > psNext ;
}
if ( ! psChunk )
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventGetContextVal: Variable not found " ) ;
return false ;
2007-06-28 10:47:08 -07:00
}
* ppsVal = psChunk - > asVals + index ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Set a global variable value for a context
2011-03-12 17:32:15 -08:00
bool eventSetContextVar ( SCRIPT_CONTEXT * psContext , UDWORD index , INTERP_VAL * data )
2007-06-28 10:47:08 -07:00
{
2006-11-24 17:26:05 -08:00
INTERP_VAL * psVal ;
2007-06-28 10:47:08 -07:00
if ( ! eventGetContextVal ( psContext , index , & psVal ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2007-02-12 07:46:54 -08:00
if ( ! interpCheckEquiv ( psVal - > type , data - > type ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventSetContextVar: Variable type mismatch (var type: %d, data type: %d) " , psVal - > type , data - > type ) ;
return false ;
2007-06-28 10:47:08 -07:00
}
// Store the data
2007-02-23 12:45:05 -08:00
if ( data - > type = = VAL_STRING )
{
ASSERT ( data - > v . sval ! = NULL ,
" eventSetContextVar: ininitialized source string pointer " ) ;
strcpy ( psVal - > v . sval , data - > v . sval ) ;
2007-04-15 03:43:05 -07:00
free ( data - > v . sval ) ; //not needed anymore
2007-06-12 10:56:34 -07:00
data - > v . sval = NULL ;
2007-02-23 12:45:05 -08:00
}
else
{
memcpy ( psVal , data , sizeof ( INTERP_VAL ) ) ;
}
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Add a trigger to the list in order
static void eventAddTrigger ( ACTIVE_TRIGGER * psTrigger )
{
UDWORD testTime = psTrigger - > testTime ;
if ( psTrigger - > type > = TR_CALLBACKSTART )
{
// Add this to the callback trigger list
if ( psCallbackList = = NULL )
{
psTrigger - > psNext = NULL ;
psCallbackList = psTrigger ;
}
else if ( psTrigger - > type < = psCallbackList - > type )
{
psTrigger - > psNext = psCallbackList ;
psCallbackList = psTrigger ;
}
else
{
2008-04-26 08:21:23 -07:00
ACTIVE_TRIGGER * psCurr , * psPrev = NULL ;
for ( psCurr = psCallbackList ; psCurr & & psCurr - > type < psTrigger - > type ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
psPrev = psCurr ;
}
psTrigger - > psNext = psPrev - > psNext ;
psPrev - > psNext = psTrigger ;
}
}
else if ( psTrigList = = NULL )
{
psTrigger - > psNext = NULL ;
psTrigList = psTrigger ;
}
else if ( testTime < = psTrigList - > testTime )
{
psTrigger - > psNext = psTrigList ;
psTrigList = psTrigger ;
}
else
{
2008-04-26 08:21:23 -07:00
ACTIVE_TRIGGER * psCurr , * psPrev = NULL ;
for ( psCurr = psTrigList ; psCurr & & psCurr - > testTime < testTime ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
psPrev = psCurr ;
}
psTrigger - > psNext = psPrev - > psNext ;
psPrev - > psNext = psTrigger ;
}
}
2006-06-02 12:34:58 -07:00
2007-06-28 10:47:08 -07:00
// Initialise a trigger
2011-03-12 17:32:15 -08:00
static bool eventInitTrigger ( ACTIVE_TRIGGER * * ppsTrigger , SCRIPT_CONTEXT * psContext ,
2007-06-28 10:47:08 -07:00
UDWORD event , SDWORD trigger , UDWORD currTime )
{
ACTIVE_TRIGGER * psNewTrig ;
TRIGGER_DATA * psTrigData ;
UDWORD testTime ;
2010-11-20 18:18:58 -08:00
ASSERT ( event < psContext - > psCode - > numEvents , " Event out of range " ) ;
ASSERT ( trigger < psContext - > psCode - > numTriggers , " Trigger out of range " ) ;
2007-06-28 10:47:08 -07:00
if ( trigger = = - 1 )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// Get a trigger object
2010-12-05 08:25:43 -08:00
psNewTrig = ( ACTIVE_TRIGGER * ) malloc ( sizeof ( ACTIVE_TRIGGER ) ) ;
2007-06-04 13:46:30 -07:00
if ( psNewTrig = = NULL )
2007-06-28 10:47:08 -07:00
{
2007-06-04 13:46:30 -07:00
debug ( LOG_ERROR , " eventInitTrigger: Out of memory " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// Initialise the trigger
psNewTrig - > psContext = psContext ;
psContext - > triggerCount + = 1 ;
psTrigData = psContext - > psCode - > psTriggerData + trigger ;
testTime = currTime + psTrigData - > time ;
psNewTrig - > testTime = testTime ;
psNewTrig - > trigger = ( SWORD ) trigger ;
psNewTrig - > type = ( SWORD ) psTrigData - > type ;
psNewTrig - > event = ( UWORD ) event ;
psNewTrig - > offset = 0 ;
2010-11-20 18:18:58 -08:00
psNewTrig - > deactivated = false ;
2007-06-28 10:47:08 -07:00
* ppsTrigger = psNewTrig ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Load a trigger into the system from a save game
2011-03-12 17:32:15 -08:00
bool eventLoadTrigger ( UDWORD time , SCRIPT_CONTEXT * psContext ,
2007-06-28 10:47:08 -07:00
SDWORD type , SDWORD trigger , UDWORD event , UDWORD offset )
{
ACTIVE_TRIGGER * psNewTrig ;
2006-08-23 05:58:48 -07:00
ASSERT ( event < psContext - > psCode - > numEvents ,
" eventLoadTrigger: Event out of range " ) ;
ASSERT ( trigger < psContext - > psCode - > numTriggers ,
" eventLoadTrigger: Trigger out of range " ) ;
2007-06-28 10:47:08 -07:00
// Get a trigger object
2010-12-05 08:25:43 -08:00
psNewTrig = ( ACTIVE_TRIGGER * ) malloc ( sizeof ( ACTIVE_TRIGGER ) ) ;
2007-06-04 13:46:30 -07:00
if ( psNewTrig = = NULL )
2007-06-28 10:47:08 -07:00
{
2009-10-30 20:57:44 -07:00
debug ( LOG_FATAL , " eventLoadTrigger: out of memory " ) ;
2006-08-22 07:28:49 -07:00
abort ( ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// Initialise the trigger
psNewTrig - > psContext = psContext ;
psContext - > triggerCount + = 1 ;
psNewTrig - > testTime = time ;
psNewTrig - > trigger = ( SWORD ) trigger ;
psNewTrig - > type = ( SWORD ) type ;
psNewTrig - > event = ( UWORD ) event ;
psNewTrig - > offset = ( UWORD ) offset ;
2010-11-20 18:18:58 -08:00
psNewTrig - > deactivated = false ;
2007-06-28 10:47:08 -07:00
eventAddTrigger ( psNewTrig ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// add a TR_PAUSE trigger to the event system.
2011-03-12 17:32:15 -08:00
bool eventAddPauseTrigger ( SCRIPT_CONTEXT * psContext , UDWORD event , UDWORD offset ,
2007-06-28 10:47:08 -07:00
UDWORD time )
{
ACTIVE_TRIGGER * psNewTrig ;
SDWORD trigger ;
2006-08-23 05:58:48 -07:00
ASSERT ( event < psContext - > psCode - > numEvents ,
" eventAddTrigger: Event out of range " ) ;
2007-06-28 10:47:08 -07:00
// Get a trigger object
2010-12-05 08:25:43 -08:00
psNewTrig = ( ACTIVE_TRIGGER * ) malloc ( sizeof ( ACTIVE_TRIGGER ) ) ;
2007-06-04 13:46:30 -07:00
if ( psNewTrig = = NULL )
2007-06-28 10:47:08 -07:00
{
2007-06-04 13:46:30 -07:00
debug ( LOG_ERROR , " eventAddPauseTrigger: Out of memory " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// figure out what type of trigger will go into the system when the pause
// finishes
switch ( psFiringTrigger - > type )
{
case TR_WAIT :
// fired by a wait trigger, no trigger to replace it
trigger = - 1 ;
break ;
case TR_PAUSE :
// fired by a pause trigger, use the trigger stored with it
trigger = psFiringTrigger - > trigger ;
break ;
default :
// just store the trigger that fired
trigger = psFiringTrigger - > trigger ;
break ;
}
// Initialise the trigger
psNewTrig - > psContext = psContext ;
psContext - > triggerCount + = 1 ;
psNewTrig - > testTime = updateTime + time ;
psNewTrig - > trigger = ( SWORD ) trigger ;
psNewTrig - > type = TR_PAUSE ;
psNewTrig - > event = ( UWORD ) event ;
psNewTrig - > offset = ( UWORD ) offset ;
2010-11-20 18:18:58 -08:00
psNewTrig - > deactivated = false ;
2007-06-28 10:47:08 -07:00
// store the new trigger
psNewTrig - > psNext = psAddedTriggers ;
psAddedTriggers = psNewTrig ;
2010-11-20 18:18:58 -08:00
// mark the trigger for deletion
psFiringTrigger - > deactivated = true ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Free up a trigger
static void eventFreeTrigger ( ACTIVE_TRIGGER * psTrigger )
{
if ( psTrigger - > psContext - > release & & psTrigger - > psContext - > triggerCount < = 1 )
{
// Free the context as well
eventRemoveContext ( psTrigger - > psContext ) ;
}
2007-06-04 13:46:30 -07:00
free ( psTrigger ) ;
2007-06-28 10:47:08 -07:00
}
// Activate a callback trigger
void eventFireCallbackTrigger ( TRIGGER_TYPE callback )
{
2010-11-20 18:15:36 -08:00
ACTIVE_TRIGGER * psPrev = NULL , * psCurr , * psNext ;
2007-06-28 10:47:08 -07:00
TRIGGER_DATA * psTrigDat ;
2011-03-19 18:52:25 -07:00
int32_t fired ; // was BOOL (int) ** see warning about conversion
2006-09-06 09:58:20 -07:00
2007-06-28 10:47:08 -07:00
if ( interpProcessorActive ( ) )
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventFireCallbackTrigger: script interpreter is already running " ) ;
2007-06-28 10:47:08 -07:00
return ;
}
//this can be called from eventProcessTriggers and so will wipe out all the current added ones
//psAddedTriggers = NULL;
2010-11-20 18:15:36 -08:00
for ( psCurr = psCallbackList ; psCurr & & psCurr - > type < = ( int ) callback ; psCurr = psNext )
2007-06-28 10:47:08 -07:00
{
2010-11-20 18:15:36 -08:00
psNext = psCurr - > psNext ;
2007-03-15 16:17:09 -07:00
if ( psCurr - > type = = ( int ) callback )
2007-06-28 10:47:08 -07:00
{
// see if the callback should be fired
2008-03-24 09:51:17 -07:00
fired = false ;
2007-06-28 10:47:08 -07:00
if ( psCurr - > type ! = TR_PAUSE )
{
2008-03-21 09:52:10 -07:00
ASSERT ( psCurr - > trigger > = 0 & & psCurr - > trigger < psCurr - > psContext - > psCode - > numTriggers ,
" eventFireCallbackTrigger: invalid trigger number " ) ;
2007-06-28 10:47:08 -07:00
psTrigDat = psCurr - > psContext - > psCode - > psTriggerData + psCurr - > trigger ;
}
else
{
psTrigDat = NULL ;
}
if ( psTrigDat & & psTrigDat - > code )
{
2008-03-21 09:52:10 -07:00
if ( ! interpRunScript ( psCurr - > psContext , IRT_TRIGGER , psCurr - > trigger , 0 ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventFireCallbackTrigger: trigger %s: code failed " ,
2008-03-21 09:52:10 -07:00
eventGetTriggerID ( psCurr - > psContext - > psCode , psCurr - > trigger ) ) ;
2007-06-28 10:47:08 -07:00
psPrev = psCurr ;
continue ;
}
if ( ! stackPopParams ( 1 , VAL_BOOL , & fired ) )
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventFireCallbackTrigger: trigger %s: code failed " ,
2008-03-21 09:52:10 -07:00
eventGetTriggerID ( psCurr - > psContext - > psCode , psCurr - > trigger ) ) ;
2007-06-28 10:47:08 -07:00
psPrev = psCurr ;
continue ;
}
}
else
{
2008-03-24 09:51:17 -07:00
fired = true ;
2007-06-28 10:47:08 -07:00
}
// run the event
if ( fired )
{
DB_TRIGINF ( psCurr , 1 ) ;
2008-03-21 09:52:10 -07:00
DB_TRACE ( " fired " , 1 ) ;
2007-06-28 10:47:08 -07:00
// remove the trigger from the list
if ( psPrev = = NULL )
{
psCallbackList = psCallbackList - > psNext ;
}
else
{
2010-11-20 18:15:36 -08:00
psPrev - > psNext = psNext ;
2007-06-28 10:47:08 -07:00
}
psFiringTrigger = psCurr ;
2010-11-20 18:18:58 -08:00
if ( ! interpRunScript ( psCurr - > psContext , IRT_EVENT , psCurr - > event , psCurr - > offset ) ) // this could set psCurr->deactivated
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventFireCallbackTrigger: event %s: code failed " ,
2008-03-21 09:52:10 -07:00
eventGetEventID ( psCurr - > psContext - > psCode , psCurr - > event ) ) ;
2007-06-28 10:47:08 -07:00
}
2010-11-20 18:18:58 -08:00
if ( psCurr - > deactivated )
2007-06-28 10:47:08 -07:00
{
// don't need to add the trigger again - just free it
eventFreeTrigger ( psCurr ) ;
}
else
{
// make sure the trigger goes back into the system
2010-11-20 18:18:58 -08:00
psCurr - > psNext = psAddedTriggers ;
psAddedTriggers = psCurr ;
2007-06-28 10:47:08 -07:00
}
}
else
{
psPrev = psCurr ;
}
}
else
{
psPrev = psCurr ;
}
}
2010-11-20 18:18:58 -08:00
// Delete marked triggers now
eventPruneLists ( ) ;
2007-06-28 10:47:08 -07:00
// Now add all the new triggers
for ( psCurr = psAddedTriggers ; psCurr ; psCurr = psNext )
{
psNext = psCurr - > psNext ;
eventAddTrigger ( psCurr ) ;
}
//clear out after added them all
psAddedTriggers = NULL ;
}
// Run a trigger
2011-03-12 17:32:15 -08:00
static bool eventFireTrigger ( ACTIVE_TRIGGER * psTrigger )
2007-06-28 10:47:08 -07:00
{
2011-03-12 17:32:15 -08:00
bool fired ;
2007-06-28 10:47:08 -07:00
INTERP_VAL sResult ;
2008-03-24 09:51:17 -07:00
fired = false ;
2010-11-20 18:18:58 -08:00
psFiringTrigger = psTrigger ;
2007-06-28 10:47:08 -07:00
// If this is a code trigger see if it fires
if ( psTrigger - > type = = TR_CODE )
{
// Run the trigger
if ( ! interpRunScript ( psTrigger - > psContext ,
IRT_TRIGGER , psTrigger - > trigger , 0 ) )
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventFireTrigger: trigger %s: code failed " ,
2006-08-23 05:58:48 -07:00
eventGetTriggerID ( psTrigger - > psContext - > psCode , psTrigger - > trigger ) ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// Get the result
sResult . type = VAL_BOOL ;
if ( ! stackPopType ( & sResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
fired = sResult . v . bval ;
}
else
{
2008-03-24 09:51:17 -07:00
fired = true ;
2007-06-28 10:47:08 -07:00
}
// If it fired run the event
if ( fired )
{
DB_TRIGINF ( psTrigger , 1 ) ;
2008-03-21 09:52:10 -07:00
DB_TRACE ( " fired " , 1 ) ;
if ( ! interpRunScript ( psTrigger - > psContext , IRT_EVENT , psTrigger - > event , psTrigger - > offset ) )
2007-06-28 10:47:08 -07:00
{
2008-03-21 09:52:10 -07:00
DB_TRACE ( ( " ******** script failed ********* " ) , 0 ) ;
2007-06-28 10:47:08 -07:00
DB_TRIGINF ( psTrigger , 0 ) ;
2008-03-24 09:51:17 -07:00
ASSERT ( false , " eventFireTrigger: event %s: code failed " ,
2008-03-21 09:52:10 -07:00
eventGetEventID ( psTrigger - > psContext - > psCode , psTrigger - > event ) ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
}
# ifdef DEBUG
else
{
DB_TRIGINF ( psTrigger , 3 ) ;
}
# endif
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// Process all the currently active triggers
void eventProcessTriggers ( UDWORD currTime )
{
ACTIVE_TRIGGER * psCurr , * psNext , * psNew ;
TRIGGER_DATA * psData ;
// Process all the current triggers
psAddedTriggers = NULL ;
updateTime = currTime ;
while ( psTrigList & & psTrigList - > testTime < = currTime )
{
psCurr = psTrigList ;
psTrigList = psTrigList - > psNext ;
// Run the trigger
2010-11-20 18:18:58 -08:00
if ( eventFireTrigger ( psCurr ) ) // This might mark the trigger for deletion
2007-06-28 10:47:08 -07:00
{
2010-11-20 18:18:58 -08:00
if ( psCurr - > deactivated | | psCurr - > type = = TR_WAIT )
2007-06-28 10:47:08 -07:00
{
// remove the trigger
eventFreeTrigger ( psCurr ) ;
}
else if ( psCurr - > type = = TR_PAUSE )
{
// restarted a paused event - replace the old trigger
if ( psCurr - > trigger ! = - 1 )
{
if ( eventInitTrigger ( & psNew , psCurr - > psContext ,
psCurr - > event , psCurr - > trigger , updateTime ) )
{
psNew - > psNext = psAddedTriggers ;
psAddedTriggers = psNew ;
}
}
// remove the TR_PAUSE trigger
eventFreeTrigger ( psCurr ) ;
}
else
{
// Add the trigger again
psData = psCurr - > psContext - > psCode - > psTriggerData +
psCurr - > trigger ;
psCurr - > testTime = currTime + psData - > time ;
psCurr - > psNext = psAddedTriggers ;
psAddedTriggers = psCurr ;
}
}
}
2010-11-20 18:18:58 -08:00
// Delete marked triggers now
eventPruneLists ( ) ;
2007-06-28 10:47:08 -07:00
// Now add all the new triggers
for ( psCurr = psAddedTriggers ; psCurr ; psCurr = psNext )
{
psNext = psCurr - > psNext ;
eventAddTrigger ( psCurr ) ;
}
//clear out after added them all
psAddedTriggers = NULL ;
}
2010-11-20 18:18:58 -08:00
// remove all marked triggers
static void eventPruneList ( ACTIVE_TRIGGER * * ppsList )
2007-06-28 10:47:08 -07:00
{
2010-11-20 18:18:58 -08:00
ACTIVE_TRIGGER * * ppsCurr = ppsList , * psTemp ;
2007-06-28 10:47:08 -07:00
2010-11-20 18:18:58 -08:00
while ( * ppsCurr )
2007-06-28 10:47:08 -07:00
{
2010-11-20 18:18:58 -08:00
if ( ( * ppsCurr ) - > deactivated )
2007-06-28 10:47:08 -07:00
{
2010-11-20 18:18:58 -08:00
psTemp = ( * ppsCurr ) - > psNext ;
free ( * ppsCurr ) ;
* ppsCurr = psTemp ;
2007-06-28 10:47:08 -07:00
}
else
{
2010-11-20 18:18:58 -08:00
ppsCurr = & ( * ppsCurr ) - > psNext ;
2007-06-28 10:47:08 -07:00
}
}
2010-11-20 18:18:58 -08:00
}
// Mark a trigger for removal from a list
static void eventMarkTriggerInList ( ACTIVE_TRIGGER * * ppsList ,
SCRIPT_CONTEXT * psContext ,
SDWORD event , SDWORD * pTrigger )
{
ACTIVE_TRIGGER * * ppsCurr ;
for ( ppsCurr = ppsList ; ; ppsCurr = & ( * ppsCurr ) - > psNext )
2007-06-28 10:47:08 -07:00
{
2010-11-20 18:18:58 -08:00
if ( ! ( * ppsCurr ) )
2007-06-28 10:47:08 -07:00
{
2010-11-20 18:18:58 -08:00
return ;
2007-06-28 10:47:08 -07:00
}
2010-11-20 18:18:58 -08:00
else if ( ( * ppsCurr ) - > event = = event & &
( * ppsCurr ) - > psContext = = psContext )
2007-06-28 10:47:08 -07:00
{
2010-11-20 18:18:58 -08:00
break ;
2007-06-28 10:47:08 -07:00
}
}
2010-11-20 18:18:58 -08:00
if ( ( * ppsCurr ) - > type = = TR_PAUSE )
{
// pause trigger, don't remove it,
// just note the type for when the pause finishes
( * ppsCurr ) - > trigger = ( SWORD ) * pTrigger ;
* pTrigger = - 1 ;
}
else
{
( * ppsCurr ) - > deactivated = true ;
}
2007-06-28 10:47:08 -07:00
}
// Change the trigger assigned to an event - to be called from script functions
2011-03-12 17:32:15 -08:00
bool eventSetTrigger ( void )
2007-06-28 10:47:08 -07:00
{
ACTIVE_TRIGGER * psTrigger ;
UDWORD event ;
SDWORD trigger ;
SCRIPT_CONTEXT * psContext ;
if ( ! stackPopParams ( 2 , VAL_EVENT , & event , VAL_TRIGGER , & trigger ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2007-02-19 06:10:44 -08:00
# ifdef REALLY_DEBUG_THIS
2007-06-28 10:47:08 -07:00
DB_TRACE ( ( " eventSetTrigger %s %s \n " ,
eventGetEventID ( psFiringTrigger - > psContext - > psCode , event ) ,
eventGetTriggerID ( psFiringTrigger - > psContext - > psCode , trigger ) ) , 2 ) ;
2007-02-19 06:10:44 -08:00
# endif
2007-06-28 10:47:08 -07:00
// See if this is the event that is running
psContext = psFiringTrigger - > psContext ;
if ( psFiringTrigger - > event = = event )
{
2010-11-20 18:18:58 -08:00
psFiringTrigger - > deactivated = true ;
2007-06-28 10:47:08 -07:00
}
else
{
2010-11-20 18:18:58 -08:00
// Mark the old trigger in the lists
eventMarkTriggerInList ( & psTrigList , psContext , event , & trigger ) ;
eventMarkTriggerInList ( & psCallbackList , psContext , event , & trigger ) ;
eventMarkTriggerInList ( & psAddedTriggers , psContext , event , & trigger ) ;
2007-06-28 10:47:08 -07:00
}
// Create a new trigger if necessary
if ( trigger > = 0 )
{
if ( ! eventInitTrigger ( & psTrigger , psFiringTrigger - > psContext ,
event , trigger , updateTime ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
psTrigger - > psNext = psAddedTriggers ;
psAddedTriggers = psTrigger ;
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// set the event tracing level - to be called from script functions
2011-03-12 17:32:15 -08:00
bool eventSetTraceLevel ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD level ;
if ( ! stackPopParams ( 1 , VAL_INT , & level ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( level < 0 )
{
level = 0 ;
}
if ( level > 3 )
{
level = 3 ;
}
eventTraceLevel = level ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}