void Q3_DeclareVariable( int type, const char *name ) { //Cannot declare the same variable twice if ( Q3_VariableDeclared( name ) != VTYPE_NONE ) return; if ( numVariables > MAX_VARIABLES ) { Q3_DebugPrint( WL_ERROR, "too many variables already declared, maximum is %d\n", MAX_VARIABLES ); return; } switch( type ) { case TK_FLOAT: varFloats[ name ] = 0.0f; break; case TK_STRING: varStrings[ name ] = "NULL"; break; case TK_VECTOR: varVectors[ name ] = "0.0 0.0 0.0"; break; default: Q3_DebugPrint( WL_ERROR, "unknown 'type' for declare() function!\n" ); return; break; } numVariables++; }
/* ============ Q3_CenterPrint Description : Prints a message in the center of the screen Return type : static void Argument : const char *format Argument : ... ============ */ static void Q3_CenterPrint ( const char *format, ... ) { va_list argptr; char text[1024]; va_start (argptr, format); Q_vsnprintf(text, sizeof(text), format, argptr); va_end (argptr); // FIXME: added '!' so you can print something that's hasn't been precached, '@' searches only for precache text // this is just a TEMPORARY placeholder until objectives are in!!! -- dmv 11/26/01 if ((text[0] == '@') || text[0] == '!') // It's a key { if( text[0] == '!') { SV_SendServerCommand( NULL, "cp \"%s\"", (text+1) ); return; } SV_SendServerCommand( NULL, "cp \"%s\"", text ); } Q3_DebugPrint( WL_VERBOSE, "%s\n", text); // Just a developers note return; }
void Q3_InitVariables( void ) { varStrings.clear(); varFloats.clear(); varVectors.clear(); if ( numVariables > 0 ) Q3_DebugPrint( WL_WARNING, "%d residual variables found!\n", numVariables ); numVariables = 0; }
void target_counter_use( gentity_t *self, gentity_t *other, gentity_t *activator ) { if ( self->count == 0 ) { return; } //gi.Printf("target_counter %s used by %s, entnum %d\n", self->targetname, activator->targetname, activator->s.number ); self->count--; if ( activator ) { Q3_DebugPrint( WL_VERBOSE, "target_counter %s used by %s (%d/%d)\n", self->targetname, activator->targetname, (self->max_health-self->count), self->max_health ); } if ( self->count ) { if ( self->target2 ) { //gi.Printf("target_counter %s firing target2 from %s, entnum %d\n", self->targetname, activator->targetname, activator->s.number ); G_UseTargets2( self, activator, self->target2 ); } return; } G_ActivateBehavior( self,BSET_USE ); if ( self->spawnflags & 128 ) { self->svFlags |= SVF_INACTIVE; } self->activator = activator; G_UseTargets( self, activator ); if ( self->count == 0 ) { if ( self->bounceCount == 0 ) { return; } self->count = self->max_health; if ( self->bounceCount > 0 ) {//-1 means bounce back forever self->bounceCount--; } } }
qboolean G_ActivateBehavior (gentity_t *self, int bset ) { bState_t bSID = (bState_t)-1; char *bs_name = NULL; if ( !self ) { return qfalse; } bs_name = self->behaviorSet[bset]; if( !(VALIDSTRING( bs_name )) ) { return qfalse; } if ( self->NPC ) { bSID = (bState_t)(GetIDForString( BSTable, bs_name )); } if(bSID > -1) { self->NPC->tempBehavior = BS_DEFAULT; self->NPC->behaviorState = bSID; } else { /* char newname[MAX_FILENAME_LENGTH]; sprintf((char *) &newname, "%s/%s", Q3_SCRIPT_DIR, bs_name ); */ //FIXME: between here and actually getting into the ICARUS_RunScript function, the stack gets blown! if ( ( ICARUS_entFilter == -1 ) || ( ICARUS_entFilter == self->s.number ) ) { Q3_DebugPrint( WL_VERBOSE, "%s attempting to run bSet %s (%s)\n", self->targetname, GetStringForID( BSETTable, bset ), bs_name ); } ICARUS_RunScript( self, va( "%s/%s", Q3_SCRIPT_DIR, bs_name ) ); } return qtrue; }
/* ============ Q3_SetVar Description : Return type : static void Argument : int taskID Argument : int entID Argument : const char *type_name Argument : const char *data ============ */ void Q3_SetVar( int taskID, int entID, const char *type_name, const char *data ) { int vret = Q3_VariableDeclared( type_name ) ; float float_data; float val = 0.0f; if ( vret != VTYPE_NONE ) { switch ( vret ) { case VTYPE_FLOAT: //Check to see if increment command if ( (val = Q3_CheckStringCounterIncrement( data )) ) { Q3_GetFloatVariable( type_name, &float_data ); float_data += val; } else { float_data = atof((char *) data); } Q3_SetFloatVariable( type_name, float_data ); break; case VTYPE_STRING: Q3_SetStringVariable( type_name, data ); break; case VTYPE_VECTOR: Q3_SetVectorVariable( type_name, (char *) data ); break; } return; } Q3_DebugPrint( WL_ERROR, "%s variable or field not found!\n", type_name ); }
void CGCam_Anything( void ) { Q3_DebugPrint( WL_WARNING, "Camera functions NOT SUPPORTED IN MP\n"); }
/* ------------------------- Q3_CameraPath ------------------------- */ static void Q3_CameraPath( const char *name ) { Q3_DebugPrint( WL_WARNING, "Q3_CameraPath: NOT SUPPORTED IN MP\n"); }
/* ------------------------- Q3_CameraFade ------------------------- */ static void Q3_CameraFade( float sr, float sg, float sb, float sa, float dr, float dg, float db, float da, float duration ) { Q3_DebugPrint( WL_WARNING, "Q3_CameraFade: NOT SUPPORTED IN MP\n"); }
/* ============ Q3_Evaluate Description : Return type : int Argument : int p1Type Argument : const char *p1 Argument : int p2Type Argument : const char *p2 Argument : int operatorType ============ */ static int Q3_Evaluate( int p1Type, const char *p1, int p2Type, const char *p2, int operatorType ) { float f1=0, f2=0; vec3_t v1, v2; char *c1=0, *c2=0; int i1=0, i2=0; //Always demote to int on float to integer comparisons if ( ( ( p1Type == TK_FLOAT ) && ( p2Type == TK_INT ) ) || ( ( p1Type == TK_INT ) && ( p2Type == TK_FLOAT ) ) ) { p1Type = TK_INT; p2Type = TK_INT; } //Cannot compare two disimilar types if ( p1Type != p2Type ) { Q3_DebugPrint( WL_ERROR, "Q3_Evaluate comparing two disimilar types!\n"); return false; } //Format the parameters switch ( p1Type ) { case TK_FLOAT: sscanf( p1, "%f", &f1 ); sscanf( p2, "%f", &f2 ); break; case TK_INT: sscanf( p1, "%d", &i1 ); sscanf( p2, "%d", &i2 ); break; case TK_VECTOR: sscanf( p1, "%f %f %f", &v1[0], &v1[1], &v1[2] ); sscanf( p2, "%f %f %f", &v2[0], &v2[1], &v2[2] ); break; case TK_STRING: case TK_IDENTIFIER: c1 = (char *) p1; c2 = (char *) p2; break; default: Q3_DebugPrint( WL_WARNING, "Q3_Evaluate unknown type used!\n"); return false; } //Compare them and return the result //FIXME: YUCK!!! Better way to do this? switch ( operatorType ) { // // EQUAL TO // case TK_EQUALS: switch ( p1Type ) { case TK_FLOAT: return (int) ( f1 == f2 ); break; case TK_INT: return (int) ( i1 == i2 ); break; case TK_VECTOR: return (int) VectorCompare( v1, v2 ); break; case TK_STRING: case TK_IDENTIFIER: return (int) !Q_stricmp( c1, c2 ); //NOTENOTE: The script uses proper string comparison logic (ex. ( a == a ) == true ) break; default: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate unknown type used!\n"); return false; } break; // // GREATER THAN // case TK_GREATER_THAN: switch ( p1Type ) { case TK_FLOAT: return (int) ( f1 > f2 ); break; case TK_INT: return (int) ( i1 > i2 ); break; case TK_VECTOR: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate vector comparisons of type GREATER THAN cannot be performed!"); return false; break; case TK_STRING: case TK_IDENTIFIER: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate string comparisons of type GREATER THAN cannot be performed!"); return false; break; default: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate unknown type used!\n"); return false; } break; // // LESS THAN // case TK_LESS_THAN: switch ( p1Type ) { case TK_FLOAT: return (int) ( f1 < f2 ); break; case TK_INT: return (int) ( i1 < i2 ); break; case TK_VECTOR: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate vector comparisons of type LESS THAN cannot be performed!"); return false; break; case TK_STRING: case TK_IDENTIFIER: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate string comparisons of type LESS THAN cannot be performed!"); return false; break; default: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate unknown type used!\n"); return false; } break; // // NOT // case TK_NOT: //NOTENOTE: Implied "NOT EQUAL TO" switch ( p1Type ) { case TK_FLOAT: return (int) ( f1 != f2 ); break; case TK_INT: return (int) ( i1 != i2 ); break; case TK_VECTOR: return (int) !VectorCompare( v1, v2 ); break; case TK_STRING: case TK_IDENTIFIER: return (int) Q_stricmp( c1, c2 ); break; default: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate unknown type used!\n"); return false; } break; default: Q3_DebugPrint( WL_ERROR, "Q3_Evaluate unknown operator used!\n"); break; } return false; }
void scriptrunner_run (gentity_t *self) { /* if (self->behaviorSet[BSET_USE]) { char newname[MAX_FILENAME_LENGTH]; sprintf((char *) &newname, "%s/%s", Q3_SCRIPT_DIR, self->behaviorSet[BSET_USE] ); ICARUS_RunScript( self, newname ); } */ if ( self->count != -1 ) { if ( self->count <= 0 ) { self->e_UseFunc = useF_NULL; self->behaviorSet[BSET_USE] = NULL; return; } else { --self->count; } } if (self->behaviorSet[BSET_USE]) { if ( self->spawnflags & 1 ) { if ( !self->activator ) { Q3_DebugPrint( WL_ERROR, "target_scriptrunner tried to run on invalid entity!\n"); return; } if ( !self->activator->sequencer || !self->activator->taskManager ) {//Need to be initialized through ICARUS if ( !self->activator->script_targetname || !self->activator->script_targetname[0] ) { //We don't have a script_targetname, so create a new one self->activator->script_targetname = va( "newICARUSEnt%d", numNewICARUSEnts++ ); } if ( ICARUS_ValidEnt( self->activator ) ) { ICARUS_InitEnt( self->activator ); } else { Q3_DebugPrint( WL_ERROR, "target_scriptrunner tried to run on invalid ICARUS activator!\n"); return; } } Q3_DebugPrint( WL_VERBOSE, "target_scriptrunner running %s on activator %s\n", self->behaviorSet[BSET_USE], self->activator->targetname ); ICARUS_RunScript( self->activator, va( "%s/%s", Q3_SCRIPT_DIR, self->behaviorSet[BSET_USE] ) ); } else { if ( self->activator ) { Q3_DebugPrint( WL_VERBOSE, "target_scriptrunner %s used by %s\n", self->targetname, self->activator->targetname ); } G_ActivateBehavior( self, BSET_USE ); } } if ( self->wait ) { self->nextthink = level.time + self->wait; } }