void G_globalInit() { char data[255]; global_t *temp = NULL; whitelist_t *whitelisttemp = NULL; level.globals = NULL; level.whitelist = NULL; if (trap_mysql_runquery(va("SELECT HIGH_PRIORITY * FROM globals ORDER BY id ASC")) == qtrue) { while (trap_mysql_fetchrow() == qtrue) { temp = G_Alloc(sizeof(global_t)); trap_mysql_fetchfieldbyName("id", data, sizeof(data)); temp->id = atoi(data); trap_mysql_fetchfieldbyName("adminname", temp->adminName, sizeof(temp->adminName)); trap_mysql_fetchfieldbyName("ip", temp->ip, sizeof(temp->ip)); trap_mysql_fetchfieldbyName("guid", temp->guid, sizeof(temp->guid)); trap_mysql_fetchfieldbyName("name", temp->playerName, sizeof(temp->playerName)); trap_mysql_fetchfieldbyName("reason", temp->reason, sizeof(temp->reason)); trap_mysql_fetchfieldbyName("server", temp->server, sizeof(temp->server)); trap_mysql_fetchfieldbyName("subnet", data, sizeof(data)); temp->subnet = atoi(data); trap_mysql_fetchfieldbyName("type", data, sizeof(data)); temp->type = atoi(data); temp->next = level.globals; level.globals = temp; } trap_mysql_finishquery(); } else { G_LogPrintf("Query Failed on GlobalInit, data base is probably disconnected, try !reconnectdb\n"); } if (trap_mysql_runquery(va("SELECT HIGH_PRIORITY * FROM whitelist ORDER BY id ASC")) == qtrue) { while (trap_mysql_fetchrow() == qtrue) { whitelisttemp = G_Alloc(sizeof(whitelist_t)); trap_mysql_fetchfieldbyName("id", data, sizeof(data)); whitelisttemp->id = atoi(data); trap_mysql_fetchfieldbyName("adminname", whitelisttemp->adminName, sizeof(whitelisttemp->adminName)); trap_mysql_fetchfieldbyName("ip", whitelisttemp->ip, sizeof(whitelisttemp->ip)); trap_mysql_fetchfieldbyName("guid", whitelisttemp->guid, sizeof(whitelisttemp->guid)); trap_mysql_fetchfieldbyName("playername", whitelisttemp->playerName, sizeof(whitelisttemp->playerName)); trap_mysql_fetchfieldbyName("reason", whitelisttemp->reason, sizeof(whitelisttemp->reason)); whitelisttemp->next = level.whitelist; level.whitelist = whitelisttemp; } trap_mysql_finishquery(); } }
/* ============= G_NewString Builds a copy of the string, translating \n to real linefeeds so message texts can be multi-line ============= */ char *G_NewString( const char *string ) { char *newb, *new_p; int i,l; l = strlen(string) + 1; newb = G_Alloc( l ); new_p = newb; // turn \n into a real linefeed for ( i=0 ; i< l ; i++ ) { if (string[i] == '\\' && i < l-1) { i++; if (string[i] == 'n') { *new_p++ = '\n'; } else { *new_p++ = '\\'; } } else { *new_p++ = string[i]; } } return newb; }
/* ============== AICast_SetupClient ============== */ int AICast_SetupClient(int client) { cast_state_t *cs; bot_state_t *bs; if (!botstates[client]) { botstates[client] = G_Alloc(sizeof(bot_state_t)); memset( botstates[client], 0, sizeof(bot_state_t) ); } bs = botstates[client]; if (bs->inuse) { BotAI_Print(PRT_FATAL, "client %d already setup\n", client); return qfalse; } cs = AICast_GetCastState(client); cs->bs = bs; //allocate a goal state bs->gs = trap_BotAllocGoalState(client); bs->inuse = qtrue; bs->client = client; bs->entitynum = client; bs->setupcount = qtrue; bs->entergame_time = trap_AAS_Time(); bs->ms = trap_BotAllocMoveState(); return qtrue; }
/* ============= G_NewString Builds a copy of the string, translating \n to real linefeeds so message texts can be multi-line ============= */ char *G_NewString( const char *string ) { char *newb=NULL, *new_p=NULL; int i=0, len=0; len = strlen( string )+1; new_p = newb = (char *)G_Alloc( len ); for ( i=0; i<len; i++ ) {// turn \n into a real linefeed if ( string[i] == '\\' && i < len-1 ) { if ( string[i+1] == 'n' ) { *new_p++ = '\n'; i++; } else *new_p++ = '\\'; } else *new_p++ = string[i]; } return newb; }
/* ============= AICast_ScriptLoad Loads the script for the current level into the buffer ============= */ void AICast_ScriptLoad( void ) { char filename[MAX_QPATH]; vmCvar_t mapname; fileHandle_t f; int len; level.scriptAI = NULL; trap_Cvar_VariableStringBuffer( "ai_scriptName", filename, sizeof( filename ) ); if ( strlen( filename ) > 0 ) { trap_Cvar_Register( &mapname, "ai_scriptName", "", CVAR_ROM ); } else { trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM ); } Q_strncpyz( filename, "maps/", sizeof( filename ) ); Q_strcat( filename, sizeof( filename ), mapname.string ); Q_strcat( filename, sizeof( filename ), ".ai" ); len = trap_FS_FOpenFile( filename, &f, FS_READ ); // make sure we clear out the temporary scriptname trap_Cvar_Set( "ai_scriptName", "" ); if ( len < 0 ) { return; } level.scriptAI = G_Alloc( len ); trap_FS_Read( level.scriptAI, len, f ); trap_FS_FCloseFile( f ); return; }
/* =================== G_ScriptAction_TagConnect syntax: attachtotag <targetname/scriptname> <tagname> connect this entity onto the tag of another entity =================== */ qboolean G_ScriptAction_TagConnect( gentity_t *ent, char *params ) { char *pString, *token; gentity_t *parent; pString = params; token = COM_Parse( &pString ); if ( !token[0] ) { G_Error( "G_ScriptAction_TagConnect: syntax: attachtotag <targetname> <tagname>\n" ); } parent = G_Find( NULL, FOFS( targetname ), token ); if ( !parent ) { parent = G_Find( NULL, FOFS( scriptName ), token ); if ( !parent ) { G_Error( "G_ScriptAction_TagConnect: unable to find entity with targetname \"%s\"", token ); } } token = COM_Parse( &pString ); if ( !token[0] ) { G_Error( "G_ScriptAction_TagConnect: syntax: attachtotag <targetname> <tagname>\n" ); } ent->tagParent = parent; ent->tagName = G_Alloc( strlen( token ) + 1 ); Q_strncpyz( ent->tagName, token, strlen( token ) + 1 ); G_ProcessTagConnect( ent, qtrue ); return qtrue; }
/* =============== G_ParseInfos =============== */ int G_ParseInfos(char *buf, int max, char *infos[]) { char *token; int count; char key[MAX_TOKEN_CHARS]; char info[MAX_INFO_STRING]; count = 0; while(1) { token = Com_Parse(&buf); if(!token[0]) { break; } if(strcmp(token, "{")) { Com_Printf("Missing { in info file\n"); break; } if(count == max) { Com_Printf("Max infos exceeded\n"); break; } info[0] = '\0'; while(1) { token = Com_ParseExt(&buf, qtrue); if(!token[0]) { Com_Printf("Unexpected end of info file\n"); break; } if(!strcmp(token, "}")) { break; } Q_strncpyz(key, token, sizeof(key)); token = Com_ParseExt(&buf, qfalse); if(!token[0]) { strcpy(token, "<NULL>"); } Info_SetValueForKey(info, key, token); } //NOTE: extra space for arena number infos[count] = G_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1); if(infos[count]) { strcpy(infos[count], info); count++; } } return count; }
/* ============= G_Script_ScriptLoad Loads the script for the current level into the buffer ============= */ void G_Script_ScriptLoad(void) { char filename[MAX_QPATH]; vmCvar_t mapname; fileHandle_t f; int len; trap_Cvar_Register(&g_scriptDebug, "g_scriptDebug", "0", 0); level.scriptEntity = NULL; trap_Cvar_VariableStringBuffer("g_scriptName", filename, sizeof(filename)); if (strlen(filename) > 0) { trap_Cvar_Register(&mapname, "g_scriptName", "", CVAR_CHEAT); } else { trap_Cvar_Register(&mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM); } Q_strncpyz(filename, "maps/", sizeof(filename)); Q_strcat(filename, sizeof(filename), mapname.string); if (g_gametype.integer == GT_WOLF_LMS) { Q_strcat(filename, sizeof(filename), "_lms"); } Q_strcat(filename, sizeof(filename), ".script"); len = trap_FS_FOpenFile(filename, &f, FS_READ); // make sure we clear out the temporary scriptname trap_Cvar_Set("g_scriptName", ""); if (len < 0) { return; } // END Mad Doc - TDF // Arnout: make sure we terminate the script with a '\0' to prevent parser from choking //level.scriptEntity = G_Alloc( len ); //trap_FS_Read( level.scriptEntity, len, f ); level.scriptEntity = G_Alloc(len + 1); trap_FS_Read(level.scriptEntity, len, f); *(level.scriptEntity + len) = '\0'; // Gordon: and make sure ppl haven't put stuff with uppercase in the string table.. G_Script_EventStringInit(); // Gordon: discard all the comments NOW, so we dont deal with them inside scripts // Gordon: disabling for a sec, wanna check if i can get proper line numbers from error output // COM_Compress( level.scriptEntity ); trap_FS_FCloseFile(f); }
/* =============== AICast_DBG_Spawn_f =============== */ void AICast_DBG_Spawn_f( gclient_t *client, char *cmd ) { extern qboolean G_CallSpawn( gentity_t *ent ); gentity_t *ent; vec3_t dir; ent = G_Spawn(); ent->classname = G_Alloc( strlen( cmd ) + 1 ); strcpy( ent->classname, cmd ); AngleVectors( client->ps.viewangles, dir, NULL, NULL ); VectorMA( client->ps.origin, 96, dir, ent->s.origin ); if ( !G_CallSpawn( ent ) ) { G_Printf( "Error: unable to spawn \"%s\" entity\n", cmd ); } }
qboolean JKG_Arrays_AddArrayElement_Location(int index, void **arry, size_t sze, unsigned int *count){ char *buf; int shiftCount; *arry = (void *)realloc(*arry, sze * ((*count) + 1)); if(!arry) { trap->Error(ERR_DROP, "JKG_Arrays_AddArrayElement_Location: Failed to realloc memory array!\n"); return qfalse; } shiftCount = (*count - index) * sze; buf = (char *)G_Alloc(shiftCount); memcpy(buf, (byte *)(*arry) + (index * sze), shiftCount); memcpy((byte *)(*arry) + ((index + 1) * sze), buf, shiftCount); memset((byte *)(*arry) + (index * sze), 0, sze); (*count)++; return qtrue; }
/* ================== L0 - Splits string into tokens ================== */ void Q_Tokenize(char *str, char **splitstr, char *delim) { char *p; int i = 0; p = strtok(str, delim); while (p != NULL) { printf("%s", p); splitstr[i] = G_Alloc(strlen(p) + 1); if (splitstr[i]) strcpy(splitstr[i], p); i++; p = strtok(NULL, delim); } }
void SP_team_WOLF_objective(gentity_t *ent) { char *desc; G_SpawnString("description", "WARNING: No objective description set", &desc); // Gordon: wtf is this g_alloced? just use a static buffer fgs... ent->message = G_Alloc(strlen(desc) + 1); Q_strncpyz(ent->message, desc, strlen(desc) + 1); ent->nextthink = level.time + FRAMETIME; ent->think = objective_Register; ent->s.eType = ET_WOLF_OBJECTIVE; if (ent->spawnflags & 1) { ent->count2 = TEAM_AXIS; } else if (ent->spawnflags & 2) { ent->count2 = TEAM_ALLIES; } }
void AICast_Init (void) { vmCvar_t cvar; int i; numSecrets = 0; numcast = 0; numSpawningCast = 0; saveGamePending = qtrue; trap_Cvar_Register( &aicast_debug, "aicast_debug", "0", 0 ); trap_Cvar_Register( &aicast_debugname, "aicast_debugname", "", 0 ); trap_Cvar_Register( &aicast_scripts, "aicast_scripts", "1", 0 ); // (aicast_thinktime / sv_fps) * aicast_maxthink = number of cast's to think between each aicast frame // so.. // (100 / 20) * 6 = 30 // // so if the level has more than 30 AI cast's, they could start to bunch up, resulting in slower thinks trap_Cvar_Register( &cvar, "aicast_thinktime", "50", 0 ); aicast_thinktime = trap_Cvar_VariableIntegerValue( "aicast_thinktime" ); trap_Cvar_Register( &cvar, "aicast_maxthink", "12", 0 ); aicast_maxthink = trap_Cvar_VariableIntegerValue( "aicast_maxthink" ); aicast_maxclients = trap_Cvar_VariableIntegerValue( "sv_maxclients" ); aicast_skillscale = (float)trap_Cvar_VariableIntegerValue( "g_gameSkill" ) / (float)GSKILL_MAX; caststates = G_Alloc( aicast_maxclients * sizeof(cast_state_t) ); memset( caststates, 0, sizeof(caststates) ); for (i=0; i<MAX_CLIENTS; i++) { caststates[i].entityNum = i; } // try and load in the AAS now, so we can interact with it during spawning of entities i = 0; trap_AAS_SetCurrentWorld(0); while (!trap_AAS_Initialized() && (i++ < 10)) { trap_BotLibStartFrame((float) level.time / 1000); } }
/* =================== G_ScriptAction_TagConnect syntax: attachtotag <targetname/scriptname> <tagname> connect this entity onto the tag of another entity =================== */ qboolean G_ScriptAction_TagConnect( gentity_t *ent, char *params ) { char *pString, *token; gentity_t *parent; pString = params; token = COM_Parse(&pString); if (!token[0]) { G_Error( "G_ScriptAction_TagConnect: syntax: attachtotag <targetname> <tagname>\n" ); } parent = G_Find( NULL, FOFS(targetname), token ); if (!parent) { parent = G_Find( NULL, FOFS(scriptName), token ); if (!parent) { G_Error( "G_ScriptAction_TagConnect: unable to find entity with targetname \"%s\"", token ); } } token = COM_Parse(&pString); if (!token[0]) { G_Error( "G_ScriptAction_TagConnect: syntax: attachtotag <targetname> <tagname>\n" ); } ent->tagParent = parent; ent->tagName = G_Alloc(strlen(token)+1); Q_strncpyz( ent->tagName, token, strlen(token)+1 ); G_ProcessTagConnect( ent ); // clear out the angles so it always starts out facing the tag direction VectorClear( ent->s.angles ); VectorCopy( ent->s.angles, ent->s.apos.trBase ); ent->s.apos.trTime = level.time; ent->s.apos.trDuration = 0; ent->s.apos.trType = TR_STATIONARY; VectorClear( ent->s.apos.trDelta ); return qtrue; }
/* ============= G_Script_ScriptLoad Loads the script for the current level into the buffer ============= */ void G_Script_ScriptLoad( void ) { char filename[MAX_QPATH]; vmCvar_t mapname; fileHandle_t f; int len; trap_Cvar_Register( &g_scriptDebug, "g_scriptDebug", "0", 0 ); level.scriptEntity = NULL; trap_Cvar_VariableStringBuffer( "g_scriptName", filename, sizeof( filename ) ); if ( strlen( filename ) > 0 ) { trap_Cvar_Register( &mapname, "g_scriptName", "", CVAR_ROM ); } else { trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM ); } Q_strncpyz( filename, "maps/", sizeof( filename ) ); Q_strcat( filename, sizeof( filename ), mapname.string ); // DHM - Nerve :: Support capture mode by loading appropriate script if ( ( g_gametype.integer == GT_WOLF_CP ) || ( g_gametype.integer == GT_WOLF_CPH ) ) { // JPW NERVE added capture & hold Q_strcat( filename, sizeof( filename ), "_cp" ); } // dhm - Nerve Q_strcat( filename, sizeof( filename ), ".script" ); len = trap_FS_FOpenFile( filename, &f, FS_READ ); // make sure we clear out the temporary scriptname trap_Cvar_Set( "g_scriptName", "" ); if ( len < 0 ) { return; } level.scriptEntity = G_Alloc( len ); trap_FS_Read( level.scriptEntity, len, f ); trap_FS_FCloseFile( f ); }
static qboolean G_InitRoff( char *file, unsigned char *data ) { roff_hdr_t *header = (roff_hdr_t *)data; int count = (int)header->mCount; int i; roffs[num_roffs].fileName = G_NewString( file ); if ( header->mVersion == ROFF_VERSION ) { // We are Old School(tm) roffs[num_roffs].type = 1; roffs[num_roffs].data = (void *) G_Alloc( count * sizeof( move_rotate_t ) ); move_rotate_t *mem = (move_rotate_t *)roffs[num_roffs].data; roffs[num_roffs].mFrameTime = 100; // old school ones have a hard-coded frame time roffs[num_roffs].mLerp = 10; roffs[num_roffs].mNumNoteTracks = 0; roffs[num_roffs].mNoteTrackIndexes = NULL; if ( mem ) { // The allocation worked, so stash this stuff off so we can reference the data later if needed roffs[num_roffs].frames = count; // Step past the header to get to the goods move_rotate_t *roff_data = ( move_rotate_t *)&header[1]; // Copy all of the goods into our ROFF cache for ( int i = 0; i < count; i++, roff_data++, mem++ ) { // Copy just the delta position and orientation which can be applied to anything at a later point VectorCopy( roff_data->origin_delta, mem->origin_delta ); VectorCopy( roff_data->rotate_delta, mem->rotate_delta ); } return qtrue; } } else if ( header->mVersion == ROFF_VERSION2 ) { // Version 2.0, heck yeah! roff_hdr2_t *hdr = (roff_hdr2_t *)data; count = hdr->mCount; roffs[num_roffs].frames = count; roffs[num_roffs].data = (void *) G_Alloc( count * sizeof( move_rotate2_t )); move_rotate2_t *mem = (move_rotate2_t *)roffs[num_roffs].data; if ( mem ) { roffs[num_roffs].mFrameTime = hdr->mFrameRate; roffs[num_roffs].mLerp = 1000 / hdr->mFrameRate; roffs[num_roffs].mNumNoteTracks = hdr->mNumNotes; if (roffs[num_roffs].mFrameTime < 50) { Com_Printf(S_COLOR_RED"Error: \"%s\" has an invalid ROFF framerate (%d < 50)\n", file, roffs[num_roffs].mFrameTime); } assert( roffs[num_roffs].mFrameTime >= 50 );//HAS to be at least 50 to be reliable // Step past the header to get to the goods move_rotate2_t *roff_data = ( move_rotate2_t *)&hdr[1]; roffs[num_roffs].type = 2; //rww - any reason this wasn't being set already? // Copy all of the goods into our ROFF cache for ( i = 0; i < count; i++ ) { VectorCopy( roff_data[i].origin_delta, mem[i].origin_delta ); VectorCopy( roff_data[i].rotate_delta, mem[i].rotate_delta ); mem[i].mStartNote = roff_data[i].mStartNote; mem[i].mNumNotes = roff_data[i].mNumNotes; } if ( hdr->mNumNotes ) { int size; char *ptr, *start; ptr = start = (char *)&roff_data[i]; size = 0; for( i = 0; i < hdr->mNumNotes; i++ ) { size += strlen(ptr) + 1; ptr += strlen(ptr) + 1; } // ? Get rid of dynamic memory ? roffs[num_roffs].mNoteTrackIndexes = new char *[hdr->mNumNotes]; ptr = roffs[num_roffs].mNoteTrackIndexes[0] = new char[size]; memcpy(roffs[num_roffs].mNoteTrackIndexes[0], start, size); for( i = 1; i < hdr->mNumNotes; i++ ) { ptr += strlen(ptr) + 1; roffs[num_roffs].mNoteTrackIndexes[i] = ptr; } } return qtrue; } } return false; }
qboolean G_InitRoff( char *file, unsigned char *data ) { roff_hdr_t *header = (roff_hdr_t *)data; int count = (int)header->mCount; roffs[num_roffs].fileName = G_NewString( file ); if ( header->mVersion == ROFF_VERSION ) { // We are Old School(tm) roffs[num_roffs].data = (void *) G_Alloc( count * sizeof( move_rotate_t ) ); move_rotate_t *mem = (move_rotate_t *)roffs[num_roffs].data; roffs[num_roffs].mFrameTime = 100; // old school ones have a hard-coded frame time roffs[num_roffs].mLerp = 10; if ( mem ) { // The allocation worked, so stash this stuff off so we can reference the data later if needed roffs[num_roffs].frames = count; // Step past the header to get to the goods move_rotate_t *roff_data = ( move_rotate_t *)&header[1]; // Copy all of the goods into our ROFF cache for ( int i = 0; i < count; i++, roff_data++, mem++ ) { // Copy just the delta position and orientation which can be applied to anything at a later point VectorCopy( roff_data->origin_delta, mem->origin_delta ); VectorCopy( roff_data->rotate_delta, mem->rotate_delta ); } } else { return qfalse; } } else { // Version 2.0, heck yeah! roff_hdr2_t *hdr = (roff_hdr2_t *)data; count = hdr->mCount; roffs[num_roffs].frames = count; roffs[num_roffs].data = (void *) G_Alloc( count * sizeof( move_rotate2_t )); move_rotate2_t *mem = (move_rotate2_t *)roffs[num_roffs].data; if ( mem ) { roffs[num_roffs].mFrameTime = hdr->mFrameRate; roffs[num_roffs].mLerp = 1000 / hdr->mFrameRate; roffs[num_roffs].mNumNoteTracks = hdr->mNumNotes; // Step past the header to get to the goods move_rotate2_t *roff_data = ( move_rotate2_t *)&hdr[1]; roffs[num_roffs].type = 2; //rww - any reason this wasn't being set already? // Copy all of the goods into our ROFF cache for ( int i = 0; i < count; i++ ) { VectorCopy( roff_data[i].origin_delta, mem[i].origin_delta ); VectorCopy( roff_data[i].rotate_delta, mem[i].rotate_delta ); mem[i].mStartNote = roff_data[i].mStartNote; mem[i].mNumNotes = roff_data[i].mNumNotes; } #if itCouldHappenToAnyoneOfUs if ( hdr->mNumNotes ) { int size; char *ptr, *start; ptr = start = (char *)&roff_data[i]; //<-- Boot: Why. How did they even compile ok I'm outta here SHIT DINOSAURSSFFK size = 0; for(int i = 0; i < hdr->mNumNotes; i++ ) { size += strlen(ptr) + 1; ptr += strlen(ptr) + 1; } // ? Get rid of dynamic memory ? roffs[num_roffs].mNoteTrackIndexes = new char *[hdr->mNumNotes]; ptr = roffs[num_roffs].mNoteTrackIndexes[0] = new char[size]; memcpy(roffs[num_roffs].mNoteTrackIndexes[0], start, size); for(int i = 1; i < hdr->mNumNotes; i++ ) { ptr += strlen(ptr) + 1; roffs[num_roffs].mNoteTrackIndexes[i] = ptr; } } #endif } else { return false; } } return true; }
void AICast_ScriptParse( cast_state_t *cs ) { #define MAX_SCRIPT_EVENTS 64 gentity_t *ent; char *pScript; char *token; qboolean wantName; qboolean inScript; int eventNum; cast_script_event_t events[MAX_SCRIPT_EVENTS]; int numEventItems; cast_script_event_t *curEvent; char params[MAX_QPATH]; cast_script_stack_action_t *action; int i; int bracketLevel; qboolean buildScript; //----(SA) added if ( !level.scriptAI ) { return; } ent = &g_entities[cs->entityNum]; if ( !ent->aiName ) { return; } buildScript = trap_Cvar_VariableIntegerValue( "com_buildScript" ); buildScript = qtrue; pScript = level.scriptAI; wantName = qtrue; inScript = qfalse; COM_BeginParseSession( "AICast_ScriptParse" ); bracketLevel = 0; numEventItems = 0; memset( events, 0, sizeof( events ) ); while ( 1 ) { token = COM_Parse( &pScript ); if ( !token[0] ) { if ( !wantName ) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } break; } // end of script if ( token[0] == '}' ) { if ( inScript ) { break; } if ( wantName ) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' found, but not expected.\n", COM_GetCurrentParseLine() ); } wantName = qtrue; } else if ( token[0] == '{' ) { if ( wantName ) { G_Error( "AICast_ScriptParse(), Error (line %d): '{' found, NAME expected.\n", COM_GetCurrentParseLine() ); } } else if ( wantName ) { if ( !Q_strcasecmp( ent->aiName, token ) ) { inScript = qtrue; numEventItems = 0; } wantName = qfalse; } else if ( inScript ) { if ( !Q_strcasecmp( token, "attributes" ) ) { // read in all the attributes AICast_CheckLevelAttributes( cs, ent, &pScript ); continue; } eventNum = AICast_EventForString( token ); if ( eventNum < 0 ) { G_Error( "AICast_ScriptParse(), Error (line %d): unknown event: %s.\n", COM_GetCurrentParseLine(), token ); } if ( numEventItems >= MAX_SCRIPT_EVENTS ) { G_Error( "AICast_ScriptParse(), Error (line %d): MAX_SCRIPT_EVENTS reached (%d)\n", COM_GetCurrentParseLine(), MAX_SCRIPT_EVENTS ); } // if this is a "friendlysightcorpse" event, then disable corpse vis sharing if ( !Q_stricmp( token, "friendlysightcorpse" ) ) { cs->aiFlags &= ~AIFL_CORPSESIGHTING; } curEvent = &events[numEventItems]; curEvent->eventNum = eventNum; memset( params, 0, sizeof( params ) ); // parse any event params before the start of this event's actions while ( ( token = COM_Parse( &pScript ) ) && ( token[0] != '{' ) ) { if ( !token[0] ) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } if ( eventNum == 13 ) { // statechange event, check params if ( strlen( token ) > 1 ) { if ( BG_IndexForString( token, animStateStr, qtrue ) < 0 ) { G_Error( "AICast_ScriptParse(), Error (line %d): unknown state type '%s'.\n", COM_GetCurrentParseLine(), token ); } } } if ( strlen( params ) ) { // add a space between each param Q_strcat( params, sizeof( params ), " " ); } Q_strcat( params, sizeof( params ), token ); } if ( strlen( params ) ) { // copy the params into the event curEvent->params = G_Alloc( strlen( params ) + 1 ); Q_strncpyz( curEvent->params, params, strlen( params ) + 1 ); } // parse the actions for this event while ( ( token = COM_Parse( &pScript ) ) && ( token[0] != '}' ) ) { if ( !token[0] ) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } action = AICast_ActionForString( cs, token ); if ( !action ) { G_Error( "AICast_ScriptParse(), Error (line %d): unknown action: %s.\n", COM_GetCurrentParseLine(), token ); } curEvent->stack.items[curEvent->stack.numItems].action = action; memset( params, 0, sizeof( params ) ); token = COM_ParseExt( &pScript, qfalse ); for ( i = 0; token[0]; i++ ) { if ( strlen( params ) ) { // add a space between each param Q_strcat( params, sizeof( params ), " " ); } if ( i == 0 ) { // Special case: playsound's need to be cached on startup to prevent in-game pauses if ( !Q_stricmp( action->actionString, "playsound" ) ) { G_SoundIndex( token ); } //----(SA) added a bit more if ( buildScript && ( !Q_stricmp( action->actionString, "mu_start" ) || !Q_stricmp( action->actionString, "mu_play" ) || !Q_stricmp( action->actionString, "mu_queue" ) || !Q_stricmp( action->actionString, "startcam" ) || !Q_stricmp( action->actionString, "startcamblack" ) ) ) { if ( strlen( token ) ) { // we know there's a [0], but don't know if it's '0' trap_SendServerCommand( cs->entityNum, va( "addToBuild %s\n", token ) ); } } if ( !Q_stricmp( action->actionString, "giveweapon" ) ) { // register weapon for client pre-loading gitem_t *weap = BG_FindItem2( token ); // (SA) FIXME: rats, need to fix this for weapon names with spaces: 'mauser rifle' // if(weap) RegisterItem( weap ); // don't be nice, just do it. if it can't find it, you'll bomb out to the error menu } //----(SA) end } if ( strrchr( token,' ' ) ) { // need to wrap this param in quotes since it has more than one word Q_strcat( params, sizeof( params ), "\"" ); } Q_strcat( params, sizeof( params ), token ); if ( strrchr( token,' ' ) ) { // need to wrap this param in quotes since it has more than one word Q_strcat( params, sizeof( params ), "\"" ); } token = COM_ParseExt( &pScript, qfalse ); } if ( strlen( params ) ) { // copy the params into the event curEvent->stack.items[curEvent->stack.numItems].params = G_Alloc( strlen( params ) + 1 ); Q_strncpyz( curEvent->stack.items[curEvent->stack.numItems].params, params, strlen( params ) + 1 ); } curEvent->stack.numItems++; if ( curEvent->stack.numItems >= AICAST_MAX_SCRIPT_STACK_ITEMS ) { G_Error( "AICast_ScriptParse(): script exceeded MAX_SCRIPT_ITEMS (%d), line %d\n", AICAST_MAX_SCRIPT_STACK_ITEMS, COM_GetCurrentParseLine() ); } } numEventItems++; } else // skip this character completely { // TTimo: gcc: suggest () around assignment used as truth value while ( ( token = COM_Parse( &pScript ) ) ) { if ( !token[0] ) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } else if ( token[0] == '{' ) { bracketLevel++; } else if ( token[0] == '}' ) { if ( !--bracketLevel ) { break; } } } } } // alloc and copy the events into the cast_state_t for this cast if ( numEventItems > 0 ) { cs->castScriptEvents = G_Alloc( sizeof( cast_script_event_t ) * numEventItems ); memcpy( cs->castScriptEvents, events, sizeof( cast_script_event_t ) * numEventItems ); cs->numCastScriptEvents = numEventItems; cs->castScriptStatus.castScriptEventIndex = -1; } }
/* ============== BotAISetupClient ============== */ int BotAISetupClient( int client, struct bot_settings_s *settings ) { char filename[MAX_PATH], name[MAX_PATH], gender[MAX_PATH]; bot_state_t *bs; int errnum; if ( !botstates[client] ) { botstates[client] = G_Alloc( sizeof( bot_state_t ) ); } bs = botstates[client]; if ( bs && bs->inuse ) { BotAI_Print( PRT_FATAL, "client %d already setup\n", client ); return qfalse; } if ( !trap_AAS_Initialized() ) { BotAI_Print( PRT_FATAL, "AAS not initialized\n" ); return qfalse; } //load the bot character bs->character = trap_BotLoadCharacter( settings->characterfile, settings->skill ); if ( !bs->character ) { BotAI_Print( PRT_FATAL, "couldn't load skill %f from %s\n", settings->skill, settings->characterfile ); return qfalse; } //copy the settings memcpy( &bs->settings, settings, sizeof( bot_settings_t ) ); //allocate a goal state bs->gs = trap_BotAllocGoalState( client ); //load the item weights trap_Characteristic_String( bs->character, CHARACTERISTIC_ITEMWEIGHTS, filename, MAX_PATH ); errnum = trap_BotLoadItemWeights( bs->gs, filename ); if ( errnum != BLERR_NOERROR ) { trap_BotFreeGoalState( bs->gs ); return qfalse; } //allocate a weapon state bs->ws = trap_BotAllocWeaponState(); //load the weapon weights trap_Characteristic_String( bs->character, CHARACTERISTIC_WEAPONWEIGHTS, filename, MAX_PATH ); errnum = trap_BotLoadWeaponWeights( bs->ws, filename ); if ( errnum != BLERR_NOERROR ) { trap_BotFreeGoalState( bs->gs ); trap_BotFreeWeaponState( bs->ws ); return qfalse; } //allocate a chat state bs->cs = trap_BotAllocChatState(); //load the chat file trap_Characteristic_String( bs->character, CHARACTERISTIC_CHAT_FILE, filename, MAX_PATH ); trap_Characteristic_String( bs->character, CHARACTERISTIC_CHAT_NAME, name, MAX_PATH ); errnum = trap_BotLoadChatFile( bs->cs, filename, name ); if ( errnum != BLERR_NOERROR ) { trap_BotFreeChatState( bs->cs ); trap_BotFreeGoalState( bs->gs ); trap_BotFreeWeaponState( bs->ws ); return qfalse; } //get the gender characteristic trap_Characteristic_String( bs->character, CHARACTERISTIC_GENDER, gender, MAX_PATH ); //set the chat gender if ( *gender == 'f' || *gender == 'F' ) { trap_BotSetChatGender( bs->cs, CHAT_GENDERFEMALE ); } else if ( *gender == 'm' || *gender == 'M' ) { trap_BotSetChatGender( bs->cs, CHAT_GENDERMALE ); } else { trap_BotSetChatGender( bs->cs, CHAT_GENDERLESS );} bs->inuse = qtrue; bs->client = client; bs->entitynum = client; bs->setupcount = 4; bs->entergame_time = trap_AAS_Time(); bs->ms = trap_BotAllocMoveState(); bs->walker = trap_Characteristic_BFloat( bs->character, CHARACTERISTIC_WALKER, 0, 1 ); numbots++; if ( trap_Cvar_VariableIntegerValue( "bot_testichat" ) ) { trap_BotLibVarSet( "bot_testichat", "1" ); BotChatTest( bs ); } //NOTE: reschedule the bot thinking BotScheduleBotThink(); // return qtrue; }
void InitGame( const char *mapname, const char *spawntarget, int checkSum, const char *entities, int levelTime, int randomSeed, int globalTime, SavedGameJustLoaded_e eSavedGameJustLoaded, qboolean qbLoadTransition ) { int i; giMapChecksum = checkSum; g_eSavedGameJustLoaded = eSavedGameJustLoaded; g_qbLoadTransition = qbLoadTransition; gi.Printf ("------- Game Initialization -------\n"); gi.Printf ("gamename: %s\n", GAMEVERSION); gi.Printf ("gamedate: %s\n", __DATE__); srand( randomSeed ); G_InitCvars(); G_InitMemory(); // set some level globals memset( &level, 0, sizeof( level ) ); level.time = levelTime; level.globalTime = globalTime; Q_strncpyz( level.mapname, mapname, sizeof(level.mapname) ); if ( spawntarget != NULL && spawntarget[0] ) { Q_strncpyz( level.spawntarget, spawntarget, sizeof(level.spawntarget) ); } else { level.spawntarget[0] = 0; } G_InitWorldSession(); // initialize all entities for this game memset( g_entities, 0, MAX_GENTITIES * sizeof(g_entities[0]) ); globals.gentities = g_entities; ClearAllInUse(); // initialize all clients for this game level.maxclients = 1; level.clients = (struct gclient_s *) G_Alloc( level.maxclients * sizeof(level.clients[0]) ); // set client fields on player g_entities[0].client = level.clients; // always leave room for the max number of clients, // even if they aren't all used, so numbers inside that // range are NEVER anything but clients globals.num_entities = MAX_CLIENTS; //Set up NPC init data NPC_InitGame(); TIMER_Clear(); // //ICARUS INIT START gi.Printf("------ ICARUS Initialization ------\n"); gi.Printf("ICARUS version : %1.2f\n", ICARUS_VERSION); Interface_Init( &interface_export ); ICARUS_Init(); gi.Printf ("-----------------------------------\n"); //ICARUS INIT END // IT_LoadItemParms (); ClearRegisteredItems(); //FIXME: if this is from a loadgame, it needs to be sure to write this out whenever you do a savegame since the edges and routes are dynamic... navCalculatePaths = ( navigator.Load( mapname, checkSum ) == qfalse ); // parse the key/value pairs and spawn gentities G_SpawnEntitiesFromString( entities ); // general initialization G_FindTeams(); // SaveRegisteredItems(); gi.Printf ("-----------------------------------\n"); //randomize the rand functions byte num_calls = (byte)timeGetTime(); for(i = 0; i < (int)num_calls; i++) { rand(); } if ( navCalculatePaths ) {//not loaded - need to calc paths navCalcPathTime = level.time + START_TIME_NAV_CALC;//make sure all ents are in and linked } else {//loaded //FIXME: if this is from a loadgame, it needs to be sure to write this //out whenever you do a savegame since the edges and routes are dynamic... //OR: always do a navigator.CheckBlockedEdges() on map startup after nav-load/calc-paths navigator.pathsCalculated = qtrue;//just to be safe? Does this get saved out? No... assumed //need to do this, because combatpoint waypoints aren't saved out...? CP_FindCombatPointWaypoints(); navCalcPathTime = 0; if ( g_eSavedGameJustLoaded == eNO ) {//clear all the failed edges unless we just loaded the game (which would include failed edges) navigator.ClearAllFailedEdges(); } } player = &g_entities[0]; //Init dynamic music level.dmState = DM_EXPLORE; level.dmDebounceTime = 0; level.dmBeatTime = 0; level.curAlertID = 1;//0 is default for lastAlertEvent, so... eventClearTime = 0; }
/* ============= G_Script_ScriptLoad Loads the script for the current level into the buffer Dini mapscripts support ============= */ void G_Script_ScriptLoad( void ) { char filename[MAX_QPATH]; vmCvar_t mapname; fileHandle_t f = 0; int len = 0; qboolean found = qfalse; trap_Cvar_Register( &g_scriptDebug, "g_scriptDebug", "0", 0 ); level.scriptEntity = NULL; trap_Cvar_VariableStringBuffer( "g_scriptName", filename, sizeof(filename) ); if (strlen( filename ) > 0) { trap_Cvar_Register( &mapname, "g_scriptName", "", CVAR_CHEAT ); } else { trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM ); } // Dini, mapscript support if(tjg_mapScriptDirectory.string[0]) { G_Printf("%s: checking for custom mapscript...\n", GAMEVERSION); Q_strncpyz(filename, tjg_mapScriptDirectory.string, sizeof(filename)); Q_strcat(filename, sizeof(filename), "/"); Q_strcat( filename, sizeof(filename), mapname.string ); Q_strcat( filename, sizeof(filename), ".script" ); len = trap_FS_FOpenFile( filename, &f, FS_READ ); if(len > 0) { found = qtrue; G_Printf("%s: loaded custom mapscript!\n", GAMEVERSION); } } if(!found) { // Normal behaviour? Q_strncpyz( filename, "maps/", sizeof(filename) ); Q_strcat( filename, sizeof(filename), mapname.string ); Q_strcat( filename, sizeof(filename), ".script" ); len = trap_FS_FOpenFile( filename, &f, FS_READ ); G_Printf("%s: no custom mapscript, using default!\n", GAMEVERSION); } // make sure we clear out the temporary scriptname trap_Cvar_Set( "g_scriptName", "" ); if( len < 0 ) { return; } // END Mad Doc - TDF // Arnout: make sure we terminate the script with a '\0' to prevent parser from choking //level.scriptEntity = G_Alloc( len ); //trap_FS_Read( level.scriptEntity, len, f ); level.scriptEntity = G_Alloc( len + 1 ); trap_FS_Read( level.scriptEntity, len, f ); *(level.scriptEntity + len) = '\0'; // Gordon: and make sure ppl haven't put stuff with uppercase in the string table.. G_Script_EventStringInit(); // Gordon: discard all the comments NOW, so we dont deal with them inside scripts // Gordon: disabling for a sec, wanna check if i can get proper line numbers from error output // COM_Compress( level.scriptEntity ); trap_FS_FCloseFile( f ); }
/* ============== AICast_ScriptParse Parses the script for the given character ============== */ void AICast_ScriptParse( cast_state_t *cs ) { #define MAX_SCRIPT_EVENTS 64 gentity_t *ent; char *pScript; char *token; qboolean wantName; qboolean inScript; int eventNum; cast_script_event_t events[MAX_SCRIPT_EVENTS]; int numEventItems; cast_script_event_t *curEvent; char params[MAX_QPATH]; cast_script_stack_action_t *action; int i; int bracketLevel; if (!level.scriptAI) return; ent = &g_entities[cs->entityNum]; if (!ent->aiName) return; pScript = level.scriptAI; wantName = qtrue; inScript = qfalse; COM_BeginParseSession("AICast_ScriptParse"); bracketLevel = 0; numEventItems = 0; memset( events, 0, sizeof(events) ); while (1) { token = COM_Parse( &pScript ); if ( !token[0] ) { if ( !wantName ) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } break; } // end of script if ( token[0] == '}' ) { if ( inScript ) { break; } if ( wantName ) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' found, but not expected.\n", COM_GetCurrentParseLine() ); } wantName = qtrue; } else if ( token[0] == '{' ) { if ( wantName ) { G_Error( "AICast_ScriptParse(), Error (line %d): '{' found, NAME expected.\n", COM_GetCurrentParseLine() ); } } else if ( wantName ) { if ( !Q_strcasecmp( ent->aiName, token ) ) { inScript = qtrue; numEventItems = 0; } wantName = qfalse; } else if ( inScript ) { if ( !Q_strcasecmp( token, "attributes" ) ) { // read in all the attributes AICast_CheckLevelAttributes( cs, ent, &pScript ); continue; } eventNum = AICast_EventForString( token ); if (eventNum < 0) { G_Error( "AICast_ScriptParse(), Error (line %d): unknown event: %s.\n", COM_GetCurrentParseLine(), token ); } if (numEventItems >= MAX_SCRIPT_EVENTS) { G_Error( "AICast_ScriptParse(), Error (line %d): MAX_SCRIPT_EVENTS reached (%d)\n", COM_GetCurrentParseLine(), MAX_SCRIPT_EVENTS ); } // if this is a "friendlysightcorpse" event, then disable corpse vis sharing if (!Q_stricmp(token, "friendlysightcorpse")) { cs->aiFlags &= ~AIFL_CORPSESIGHTING; } curEvent = &events[numEventItems]; curEvent->eventNum = eventNum; memset( params, 0, sizeof(params) ); // parse any event params before the start of this event's actions while ((token = COM_Parse( &pScript )) && (token[0] != '{')) { if (!token[0]) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } if (eventNum == 13) { // statechange event, check params if (strlen( token ) > 1) { if (BG_IndexForString( token, animStateStr, qtrue ) < 0) { G_Error( "AICast_ScriptParse(), Error (line %d): unknown state type '%s'.\n", COM_GetCurrentParseLine(), token ); } } } if (strlen( params )) // add a space between each param Q_strcat( params, sizeof(params), " " ); Q_strcat( params, sizeof(params), token ); } if (strlen( params )) { // copy the params into the event curEvent->params = G_Alloc( strlen( params ) + 1 ); Q_strncpyz( curEvent->params, params, strlen(params)+1 ); } // parse the actions for this event while ((token = COM_Parse( &pScript )) && (token[0] != '}')) { if (!token[0]) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } action = AICast_ActionForString( token ); if (!action) { G_Error( "AICast_ScriptParse(), Error (line %d): unknown action: %s.\n", COM_GetCurrentParseLine(), token ); } curEvent->stack.items[curEvent->stack.numItems].action = action; memset( params, 0, sizeof(params) ); token = COM_ParseExt( &pScript, qfalse ); for (i=0; token[0]; i++) { if (strlen( params )) { // add a space between each param Q_strcat( params, sizeof(params), " " ); } // Special case: playsound's need to be cached on startup to prevent in-game pauses if ((i==0) && !Q_stricmp(action->actionString, "playsound")) { G_SoundIndex(token); } if (strrchr(token,' ')) // need to wrap this param in quotes since it has more than one word Q_strcat( params, sizeof(params), "\"" ); Q_strcat( params, sizeof(params), token ); if (strrchr(token,' ')) // need to wrap this param in quotes since it has more than one word Q_strcat( params, sizeof(params), "\"" ); token = COM_ParseExt( &pScript, qfalse ); } if (strlen( params )) { // copy the params into the event curEvent->stack.items[curEvent->stack.numItems].params = G_Alloc( strlen( params ) + 1 ); Q_strncpyz( curEvent->stack.items[curEvent->stack.numItems].params, params, strlen(params)+1 ); } curEvent->stack.numItems++; if (curEvent->stack.numItems >= AICAST_MAX_SCRIPT_STACK_ITEMS) { G_Error( "AICast_ScriptParse(): script exceeded MAX_SCRIPT_ITEMS (%d), line %d\n", AICAST_MAX_SCRIPT_STACK_ITEMS, COM_GetCurrentParseLine() ); } } numEventItems++; } else // skip this character completely { // TTimo gcc: suggest parentheses around assignment used as truth value while ( ( token = COM_Parse( &pScript ) ) ) { if (!token[0]) { G_Error( "AICast_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine() ); } else if (token[0] == '{') { bracketLevel++; } else if (token[0] == '}') { if (!--bracketLevel) break; } } } } // alloc and copy the events into the cast_state_t for this cast if (numEventItems > 0) { cs->castScriptEvents = G_Alloc( sizeof(cast_script_event_t) * numEventItems ); memcpy( cs->castScriptEvents, events, sizeof(cast_script_event_t) * numEventItems ); cs->numCastScriptEvents = numEventItems; cs->castScriptStatus.castScriptEventIndex = -1; } }
qboolean G_InitRoff( char *file, unsigned char *data ) { roff_hdr_t *header = (roff_hdr_t *)data; int count; int i; roffs[num_roffs].fileName = G_NewString( file ); if ( LittleLong(header->mVersion) == ROFF_VERSION ) { count = (int)LittleFloat(header->mCount); // We are Old School(tm) roffs[num_roffs].data = (void *) G_Alloc( count * sizeof( move_rotate_t ) ); move_rotate_t *mem = (move_rotate_t *)roffs[num_roffs].data; roffs[num_roffs].mFrameTime = 100; // old school ones have a hard-coded frame time roffs[num_roffs].mLerp = 10; if ( mem ) { // The allocation worked, so stash this stuff off so we can reference the data later if needed roffs[num_roffs].frames = count; // Step past the header to get to the goods move_rotate_t *roff_data = ( move_rotate_t *)&header[1]; // Copy all of the goods into our ROFF cache for ( i = 0; i < count; i++, roff_data++, mem++ ) { // Copy just the delta position and orientation which can be applied to anything at a later point #ifdef Q3_BIG_ENDIAN mem->origin_delta[0] = LittleFloat(roff_data->origin_delta[0]); mem->origin_delta[1] = LittleFloat(roff_data->origin_delta[1]); mem->origin_delta[2] = LittleFloat(roff_data->origin_delta[2]); mem->rotate_delta[0] = LittleFloat(roff_data->rotate_delta[0]); mem->rotate_delta[1] = LittleFloat(roff_data->rotate_delta[1]); mem->rotate_delta[2] = LittleFloat(roff_data->rotate_delta[2]); #else VectorCopy( roff_data->origin_delta, mem->origin_delta ); VectorCopy( roff_data->rotate_delta, mem->rotate_delta ); #endif } } else { return qfalse; } } else { // Version 2.0, heck yeah! roff_hdr2_t *hdr = (roff_hdr2_t *)data; count = LittleLong(hdr->mCount); roffs[num_roffs].frames = count; roffs[num_roffs].data = (void *) G_Alloc( count * sizeof( move_rotate2_t )); move_rotate2_t *mem = (move_rotate2_t *)roffs[num_roffs].data; if ( mem ) { roffs[num_roffs].mFrameTime = LittleLong(hdr->mFrameRate); roffs[num_roffs].mLerp = 1000 / LittleLong(hdr->mFrameRate); roffs[num_roffs].mNumNoteTracks = LittleLong(hdr->mNumNotes); // Step past the header to get to the goods move_rotate2_t *roff_data = ( move_rotate2_t *)&hdr[1]; roffs[num_roffs].type = 2; //rww - any reason this wasn't being set already? // Copy all of the goods into our ROFF cache for ( i = 0; i < count; i++ ) { #ifdef Q3_BIG_ENDIAN mem[i].origin_delta[0] = LittleFloat(roff_data[i].origin_delta[0]); mem[i].origin_delta[1] = LittleFloat(roff_data[i].origin_delta[1]); mem[i].origin_delta[2] = LittleFloat(roff_data[i].origin_delta[2]); mem[i].rotate_delta[0] = LittleFloat(roff_data[i].rotate_delta[0]); mem[i].rotate_delta[1] = LittleFloat(roff_data[i].rotate_delta[1]); mem[i].rotate_delta[2] = LittleFloat(roff_data[i].rotate_delta[2]); #else VectorCopy( roff_data[i].origin_delta, mem[i].origin_delta ); VectorCopy( roff_data[i].rotate_delta, mem[i].rotate_delta ); #endif mem[i].mStartNote = LittleLong(roff_data[i].mStartNote); mem[i].mNumNotes = LittleLong(roff_data[i].mNumNotes); } if ( LittleLong(hdr->mNumNotes) ) { int size; char *ptr, *start; ptr = start = (char *)&roff_data[i]; size = 0; for( i = 0; i < LittleLong(hdr->mNumNotes); i++ ) { size += strlen(ptr) + 1; ptr += strlen(ptr) + 1; } // ? Get rid of dynamic memory ? roffs[num_roffs].mNoteTrackIndexes = new char *[LittleLong(hdr->mNumNotes)]; ptr = roffs[num_roffs].mNoteTrackIndexes[0] = new char[size]; memcpy(roffs[num_roffs].mNoteTrackIndexes[0], start, size); for( i = 1; i < LittleLong(hdr->mNumNotes); i++ ) { ptr += strlen(ptr) + 1; roffs[num_roffs].mNoteTrackIndexes[i] = ptr; } } } else { return qfalse; } } return qtrue; }
/* * BotAISetupClient */ int BotAISetupClient(int client, struct bot_settings_s *settings, qbool restart) { char filename[MAX_PATH], name[MAX_PATH], gender[MAX_PATH]; bot_state_t *bs; int errnum; if(!botstates[client]) botstates[client] = G_Alloc(sizeof(bot_state_t)); bs = botstates[client]; if(bs && bs->inuse){ BotAI_Print(PRT_FATAL, "BotAISetupClient: client %d already setup\n", client); return qfalse; } if(!trap_AAS_Initialized()){ BotAI_Print(PRT_FATAL, "AAS not initialized\n"); return qfalse; } /* load the bot character */ bs->character = trap_BotLoadCharacter(settings->characterfile, settings->skill); if(!bs->character){ BotAI_Print(PRT_FATAL, "couldn't load skill %f from %s\n", settings->skill, settings->characterfile); return qfalse; } /* copy the settings */ memcpy(&bs->settings, settings, sizeof(bot_settings_t)); /* allocate a goal state */ bs->gs = trap_BotAllocGoalState(client); /* load the item weights */ trap_Characteristic_String(bs->character, CHARACTERISTIC_ITEMWEIGHTS, filename, MAX_PATH); errnum = trap_BotLoadItemWeights(bs->gs, filename); if(errnum != BLERR_NOERROR){ trap_BotFreeGoalState(bs->gs); return qfalse; } /* allocate a weapon state */ bs->ws = trap_BotAllocWeaponState(); /* load the weapon weights */ trap_Characteristic_String(bs->character, CHARACTERISTIC_WEAPONWEIGHTS, filename, MAX_PATH); errnum = trap_BotLoadWeaponWeights(bs->ws, filename); if(errnum != BLERR_NOERROR){ trap_BotFreeGoalState(bs->gs); trap_BotFreeWeaponState(bs->ws); return qfalse; } /* allocate a chat state */ bs->cs = trap_BotAllocChatState(); /* load the chat file */ trap_Characteristic_String(bs->character, CHARACTERISTIC_CHAT_FILE, filename, MAX_PATH); trap_Characteristic_String(bs->character, CHARACTERISTIC_CHAT_NAME, name, MAX_PATH); errnum = trap_BotLoadChatFile(bs->cs, filename, name); if(errnum != BLERR_NOERROR){ trap_BotFreeChatState(bs->cs); trap_BotFreeGoalState(bs->gs); trap_BotFreeWeaponState(bs->ws); return qfalse; } /* get the gender characteristic */ trap_Characteristic_String(bs->character, CHARACTERISTIC_GENDER, gender, MAX_PATH); /* set the chat gender */ if(*gender == 'f' || *gender == 'F') trap_BotSetChatGender( bs->cs, CHAT_GENDERFEMALE); else if(*gender == 'm' || *gender == 'M') trap_BotSetChatGender( bs->cs, CHAT_GENDERMALE); else trap_BotSetChatGender(bs->cs, CHAT_GENDERLESS); bs->inuse = qtrue; bs->client = client; bs->entitynum = client; bs->setupcount = 4; bs->entergame_time = FloatTime(); bs->ms = trap_BotAllocMoveState(); bs->walker = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_WALKER, 0, 1); numbots++; if(trap_cvargeti("bot_testichat")){ trap_BotLibVarSet("bot_testichat", "1"); BotChatTest(bs); } /* NOTE: reschedule the bot thinking */ BotScheduleBotThink(); /* if interbreeding start with a mutation */ if(bot_interbreed) trap_BotMutateGoalFuzzyLogic(bs->gs, 1); /* if we kept the bot client */ if(restart) BotReadSessionData(bs); /* bot has been setup succesfully */ return qtrue; }
/* ============== Bot_ScriptParseAllCharacters ============== */ void Bot_ScriptParseAllCharacters() { char *pScript; char *token; bot_script_global_data_t *bsd; char params[MAX_TOKEN_CHARS]; if(!level.scriptEntity) { return; } pScript = level.scriptEntity; COM_BeginParseSession("Bot_ScriptParse"); numScriptCharacters = 0; memset(botCharacterScriptData, 0, sizeof(botCharacterScriptData)); while(1) { token = COM_Parse(&pScript); // we are expecting a name here if(!token[0]) { // end of script break; } if(token[0] == '{' || token[0] == '}') { G_Error("Bot_ScriptParse(), Error (line %d): entry identifier expected, '%s' found.\n", 1 + COM_GetCurrentParseLine(), token); } // is this a bot? if(Q_stricmp(token, "BOT") != 0) { // not a bot, skip this whole entry SkipRestOfLine(&pScript); // skip this section SkipBracedSection(&pScript); // continue; } // this is the name if(numScriptCharacters == MAX_BOT_SCRIPT_CHARACTERS) { G_Error ("Bot_ScriptParse(), Error (line %d): MAX_BOT_SCRIPT_CHARACTERS exceeded (%i), too many bot script characters\n", 1 + COM_GetCurrentParseLine(), MAX_BOT_SCRIPT_CHARACTERS); break; } bsd = &botCharacterScriptData[numScriptCharacters++]; bsd->lineNum = 1 + COM_GetCurrentParseLine(); // read the name token = COM_Parse(&pScript); // we are expecting a name here if(!token[0]) { G_Error("Bot_ScriptParse(), Error (line %d): name expected, end of line found.\n", 1 + COM_GetCurrentParseLine()); } if(token[0] == '{' || token[0] == '}') { G_Error("Bot_ScriptParse(), Error (line %d): name expected, '%s' found.\n", 1 + COM_GetCurrentParseLine(), token); } // allocate the name bsd->name = G_Alloc(strlen(token) + 1); Q_strncpyz(bsd->name, token, strlen(token) + 1); // read the params memset(params, 0, sizeof(params)); while((token = COM_ParseExt(&pScript, qfalse)) && token[0]) { if(strlen(params) + strlen(token) >= sizeof(params)) { G_Error("Bot_ScriptParse(), Error (line %d): parameters exceed maximum size\n", 1 + COM_GetCurrentParseLine()); } if(strlen(params) > 0) { Q_strcat(params, sizeof(params), " "); } Q_strcat(params, sizeof(params), token); } // allocate the params bsd->params = G_Alloc(strlen(params) + 1); Q_strncpyz(bsd->params, params, strlen(params) + 1); // allocate memory for this character script bsd->data = G_Alloc(sizeof(bot_script_data_t)); memset(bsd->data, 0, sizeof(bot_script_data_t)); // now parse the script data for this character Bot_ScriptParse(bsd->data, &pScript); } }
static void ReadGEntities(qboolean qbAutosave) { int iCount; gi.ReadFromSaveGame('NMED', (void *)&iCount, sizeof(iCount)); int iPreviousEntRead = -1; int i; for (i=0; i<iCount; i++) { int iEntIndex; gi.ReadFromSaveGame('EDNM', (void *)&iEntIndex, sizeof(iEntIndex)); if (iEntIndex >= globals.num_entities) { globals.num_entities = iEntIndex + 1; } if (iPreviousEntRead != iEntIndex-1) { for (int j=iPreviousEntRead+1; j!=iEntIndex; j++) { if ( g_entities[j].inuse ) // not actually necessary { G_FreeEntity(&g_entities[j]); } } } iPreviousEntRead = iEntIndex; // slightly naff syntax here, but makes a few ops clearer later... // gentity_t entity; gentity_t* pEntOriginal = &entity; gentity_t* pEnt = &g_entities[iEntIndex]; *pEntOriginal = *pEnt; // struct copy, so we can refer to original pEntOriginal->ghoul2.kill(); gi.unlinkentity(pEnt); Quake3Game()->FreeEntity( pEnt ); // // sneaky: destroy the ghoul2 object within this struct before binary-loading over the top of it... // gi.G2API_LoadSaveCodeDestructGhoul2Info(pEnt->ghoul2); pEnt->ghoul2.kill(); EvaluateFields(savefields_gEntity, (byte *)pEnt, (byte *)pEntOriginal, 'GENT', sizeof(*pEnt),qfalse); pEnt->ghoul2.kill(); // now for any fiddly bits... // if (pEnt->NPC) // will be qtrue/qfalse { gNPC_t tempNPC; EvaluateFields(savefields_gNPC, (byte *)&tempNPC,(byte *)pEntOriginal->NPC, 'GNPC', sizeof (*pEnt->NPC),qfalse); // so can we pinch the original's one or do we have to alloc a new one?... // if (pEntOriginal->NPC) { // pinch this G_Alloc handle... // pEnt->NPC = pEntOriginal->NPC; } else { // original didn't have one (hmmm...), so make a new one... // //assert(0); // I want to know about this, though not in release pEnt->NPC = (gNPC_t *) G_Alloc(sizeof(*pEnt->NPC)); } // copy over the one we've just loaded... // *pEnt->NPC = tempNPC; // struct copy //FIXME: do we need to do these too? /* if ( pEnt->s.number ) {//not player G_LoadAnimFileSet( *pEnt, *pEnt->NPC_type ); G_SetSkin( *pEnt, *pEnt->NPC_type, NULL );// it probably wasn't the default skin, do we need this at all? } */ } if (pEnt->client == (gclient_t*) -2) // one of Mike G's NPC clients? { gclient_t tempGClient; EvaluateFields(savefields_gClient, (byte *)&tempGClient, (byte *)pEntOriginal->client, 'GCLI', sizeof(*pEnt->client),qtrue);//qfalse); // can we pinch the original's client handle or do we have to alloc a new one?... // if (pEntOriginal->client) { // pinch this G_Alloc handle... // pEnt->client = pEntOriginal->client; } else { // original didn't have one (hmmm...) so make a new one... // pEnt->client = (gclient_t *) G_Alloc(sizeof(*pEnt->client)); } // copy over the one we've just loaded.... // *pEnt->client = tempGClient; // struct copy if ( pEnt->s.number ) {//not player G_ReloadSaberData( pEnt ); } } // Some Icarus thing... (probably) // if (pEnt->parms) // will be qtrue/qfalse { parms_t tempParms; gi.ReadFromSaveGame('PARM', &tempParms, sizeof(tempParms)); // so can we pinch the original's one or do we have to alloc a new one?... // if (pEntOriginal->parms) { // pinch this G_Alloc handle... // pEnt->parms = pEntOriginal->parms; } else { // original didn't have one, so make a new one... // pEnt->parms = (parms_t *) G_Alloc(sizeof(*pEnt->parms)); } // copy over the one we've just loaded... // *pEnt->parms = tempParms; // struct copy } if (pEnt->m_pVehicle) // will be qtrue/qfalse { Vehicle_t tempVehicle; EvaluateFields(savefields_gVHIC, (byte *)&tempVehicle,(byte *)pEntOriginal->m_pVehicle, 'VHIC', sizeof (*pEnt->m_pVehicle),qfalse); // so can we pinch the original's one or do we have to alloc a new one?... // if (pEntOriginal->m_pVehicle) { // pinch this G_Alloc handle... // pEnt->m_pVehicle = pEntOriginal->m_pVehicle; } else { // original didn't have one, so make a new one... // pEnt->m_pVehicle = (Vehicle_t *) gi.Malloc( sizeof(Vehicle_t), TAG_G_ALLOC, qfalse ); } // copy over the one we've just loaded... // *pEnt->m_pVehicle = tempVehicle; // struct copy } // the scary ghoul2 stuff... (fingers crossed) // { char *pGhoul2Data = NULL; gi.ReadFromSaveGame('GHL2', 0, 0, (void**)&pGhoul2Data); gi.G2API_LoadGhoul2Models(pEnt->ghoul2, pGhoul2Data); // if it's going to crash anywhere... <g> gi.Free(pGhoul2Data); } // gi.unlinkentity (pEntOriginal); // ICARUS_FreeEnt( pEntOriginal ); // *pEntOriginal = *pEnt; // struct copy // qboolean qbLinked = pEntOriginal->linked; // pEntOriginal->linked = qfalse; // if (qbLinked) // { // gi.linkentity (pEntOriginal); // } // because the sytem stores sfx_t handles directly instead of the set, we have to reget the set's sfx_t... // if (pEnt->s.eType == ET_MOVER && pEnt->s.loopSound>0) { if ( VALIDSTRING( pEnt->soundSet )) { extern int BMS_MID; // from g_mover pEnt->s.loopSound = CAS_GetBModelSound( pEnt->soundSet, BMS_MID ); if (pEnt->s.loopSound == -1) { pEnt->s.loopSound = 0; } } } // NPCs and other ents store waypoints that aren't valid after a load pEnt->waypoint = 0; qboolean qbLinked = pEnt->linked; pEnt->linked = qfalse; if (qbLinked) { gi.linkentity (pEnt); } } //Read in all the entity timers TIMER_Load();//ReadEntityTimers(); if (!qbAutosave) { // now zap any g_ents that were inuse when the level was loaded, but are no longer in use in the saved version // that we've just loaded... // for (i=iPreviousEntRead+1; i<globals.num_entities; i++) { if ( g_entities[i].inuse ) // not actually necessary { G_FreeEntity(&g_entities[i]); } } //Load ICARUS information Quake3Game()->ClearEntityList(); IIcarusInterface::GetIcarus()->Load(); // check that Icarus has loaded everything it saved out by having a marker chunk after it... // static int iBlah = 1234; gi.ReadFromSaveGame('ICOK', &iBlah, sizeof(iBlah)); } if (!qbAutosave) { ReadInUseBits();//really shouldn't need to read these bits in at all, just restore them from the ents... } }
int G_globalAdd(gentity_t *adminEnt, gentity_t *victimEnt, char *guid, char *ip, char *playerName, char *reason, int subnet, char *date, globalType_t type) { global_t *temp = G_Alloc(sizeof(global_t)); char newDate[11]; char newPlayerName[MAX_NAME_LENGTH]; char newGuid[33]; char data[255]; //DATE if (date == NULL) { qtime_t qt; int t; t = trap_RealTime(&qt); Q_strncpyz(newDate, va("%04i-%02i-%02i", qt.tm_year + 1900, qt.tm_mon + 1, qt.tm_mday), 11); } else { Q_strncpyz(newDate, date, 11); } //PLAYERNAME if (playerName == NULL) { Q_strncpyz(newPlayerName, va("%s", "UnnamedPlayer"), MAX_NAME_LENGTH); } else { Q_strncpyz(newPlayerName, playerName, MAX_NAME_LENGTH); } //GUID if (guid == NULL) { Q_strncpyz(newGuid, va("%s", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), 33); } else { Q_strncpyz(newGuid, guid, 33); } //Setting Q_strncpyz(temp->guid, newGuid, 33); Q_strncpyz(temp->ip, ip, 16); Q_strncpyz(temp->playerName, newPlayerName, MAX_NAME_LENGTH); Q_strncpyz(temp->server, va("%s","z"), 2); Q_strncpyz(temp->adminName, (G_isPlayerConnected(adminEnt)) ? adminEnt->client->pers.netname : "console", MAX_NAME_LENGTH); Q_strncpyz(temp->reason, reason, MAX_STRING_CHARS); temp->subnet = subnet; temp->type = type; if (trap_mysql_runquery(va("INSERT HIGH_PRIORITY INTO globals" " (playerid,adminid,adminname,ip,guid,name,reason,subnet,type,server) " " VALUES (\"%d\",\"%d\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%d\",\"%d\",\"x\") ", (G_isPlayerConnected(victimEnt) ? victimEnt->client->pers.mysqlid : -1), (G_isPlayerConnected(adminEnt) ? adminEnt->client->pers.mysqlid : -1), (G_isPlayerConnected(adminEnt) ? adminEnt->client->pers.netname : "console"), temp->ip, temp->guid, temp->playerName, temp->reason, temp->subnet, temp->type)) == qtrue) { trap_mysql_finishquery(); if (trap_mysql_runquery(va("SELECT HIGH_PRIORITY id FROM globals ORDER BY id DESC LIMIT 1")) == qtrue) { if (trap_mysql_fetchrow() == qtrue) { trap_mysql_fetchfieldbyName("id", data, sizeof(data)); trap_mysql_finishquery(); temp->id = atoi(data); } else { G_LogPrintf("Couldnt insert global to database\n");//va("Hacked client tried to connect guid: %s ip: %s\n", guid, ip) ); if (level.globals) { temp->id = level.globals->id + 1; } else { temp->id = 1; } } } } temp->next = level.globals; level.globals = temp; return temp->id; }
/* ============= G_Script_ScriptLoad Loads the script for the current level into the buffer ============= */ void G_Script_ScriptLoad(void) { char filename[MAX_QPATH]; vmCvar_t mapname; fileHandle_t f = 0; int len = 0; qboolean found = qfalse; trap_Cvar_Register(&g_scriptDebug, "g_scriptDebug", "0", 0); trap_Cvar_VariableStringBuffer("g_scriptName", filename, sizeof (filename)); if (filename[0] != '\0') { trap_Cvar_Register(&mapname, "g_scriptName", "", CVAR_CHEAT); } else { trap_Cvar_Register(&mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM); } // Nico, if API is used and if a mapscript was sent for this map don't load any local script if (g_useAPI.integer && level.useAPImapscript) { G_Printf("%s: using custom mapscript from API!\n", GAME_VERSION); return; } // Nico, API is not in use, check if this map a special mapscript in local mapscript directory if (!g_useAPI.integer && g_mapScriptDirectory.string[0]) { G_Printf("%s: checking for local custom mapscript...\n", GAME_VERSION); Q_strncpyz(filename, g_mapScriptDirectory.string, sizeof (filename)); Q_strcat(filename, sizeof (filename), "/"); Q_strcat(filename, sizeof (filename), mapname.string); Q_strcat(filename, sizeof (filename), ".script"); len = trap_FS_FOpenFile(filename, &f, FS_READ); if (len > 0) { found = qtrue; G_Printf("%s: found local file '%s'!\n", GAME_VERSION, filename); } else { G_Printf("%s: no local file found!\n", GAME_VERSION); } } // Nico, should we use default map script or custom one? if (!found) { Q_strncpyz(filename, "maps/", sizeof (filename)); Q_strcat(filename, sizeof (filename), mapname.string); Q_strcat(filename, sizeof (filename), ".script"); len = trap_FS_FOpenFile(filename, &f, FS_READ); G_Printf("%s: using default mapscript!\n", GAME_VERSION); } // make sure we clear out the temporary scriptname trap_Cvar_Set("g_scriptName", ""); if (len < 0) { return; } // END Mad Doc - TDF // Arnout: make sure we terminate the script with a '\0' to prevent parser from choking level.scriptEntity = NULL; level.scriptEntity = G_Alloc(len + 1); trap_FS_Read(level.scriptEntity, len, f); *(level.scriptEntity + len) = '\0'; // Gordon: and make sure ppl haven't put stuff with uppercase in the string table.. G_Script_EventStringInit(); trap_FS_FCloseFile(f); }
/* ============== G_Script_ScriptParse Parses the script for the given entity ============== */ void G_Script_ScriptParse(gentity_t *ent) { char *pScript; qboolean wantName; qboolean inScript; int eventNum; g_script_event_t events[G_MAX_SCRIPT_STACK_ITEMS]; int numEventItems; g_script_event_t *curEvent; char params[MAX_INFO_STRING]; g_script_stack_action_t *action; int i; int bracketLevel; qboolean buildScript; if (!ent->scriptName) { return; } if (!level.scriptEntity) { return; } buildScript = trap_Cvar_VariableIntegerValue("com_buildScript"); pScript = level.scriptEntity; wantName = qtrue; inScript = qfalse; COM_BeginParseSession("G_Script_ScriptParse"); bracketLevel = 0; numEventItems = 0; memset(events, 0, sizeof (events)); for (;;) { char *token; token = COM_Parse(&pScript); if (!token[0]) { if (!wantName) { G_Error("G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine()); } break; } // end of script if (token[0] == '}') { if (inScript) { break; } if (wantName) { G_Error("G_Script_ScriptParse(), Error (line %d): '}' found, but not expected.\n", COM_GetCurrentParseLine()); } wantName = qtrue; } else if (token[0] == '{') { if (wantName) { G_Error("G_Script_ScriptParse(), Error (line %d): '{' found, NAME expected.\n", COM_GetCurrentParseLine()); } } else if (wantName) { if (!Q_stricmp(token, "bot")) { // a bot, skip this whole entry SkipRestOfLine(&pScript); // skip this section SkipBracedSection(&pScript); // continue; } if (!Q_stricmp(token, "entity")) { // this is an entity, so go back to look for a name continue; } if (!Q_stricmp(ent->scriptName, token)) { inScript = qtrue; numEventItems = 0; } wantName = qfalse; } else if (inScript) { Q_strlwr(token); eventNum = G_Script_EventForString(token); if (eventNum < 0) { G_Error("G_Script_ScriptParse(), Error (line %d): unknown event: %s.\n", COM_GetCurrentParseLine(), token); } if (numEventItems >= G_MAX_SCRIPT_STACK_ITEMS) { G_Error("G_Script_ScriptParse(), Error (line %d): G_MAX_SCRIPT_STACK_ITEMS reached (%d)\n", COM_GetCurrentParseLine(), G_MAX_SCRIPT_STACK_ITEMS); } curEvent = &events[numEventItems]; curEvent->eventNum = eventNum; memset(params, 0, sizeof (params)); // parse any event params before the start of this event's actions while ((token = COM_Parse(&pScript)) != NULL && (token[0] != '{')) { if (!token[0]) { G_Error("G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine()); } if (strlen(params)) { // add a space between each param Q_strcat(params, sizeof (params), " "); } Q_strcat(params, sizeof (params), token); } if (strlen(params)) { // copy the params into the event curEvent->params = G_Alloc(strlen(params) + 1); Q_strncpyz(curEvent->params, params, strlen(params) + 1); } // parse the actions for this event while ((token = COM_Parse(&pScript)) != NULL && (token[0] != '}')) { if (!token[0]) { G_Error("G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine()); } action = G_Script_ActionForString(token); if (!action) { G_Error("G_Script_ScriptParse(), Error (line %d): unknown action: %s.\n", COM_GetCurrentParseLine(), token); } curEvent->stack.items[curEvent->stack.numItems].action = action; memset(params, 0, sizeof (params)); // Ikkyo - Parse for {}'s if this is a set command // Nico, added "create" & "delete" condition if (!Q_stricmp(action->actionString, "set") || !Q_stricmp(action->actionString, "create") || !Q_stricmp(action->actionString, "delete")) { token = COM_Parse(&pScript); if (token[0] != '{') { COM_ParseError("'{' expected, found: %s.\n", token); } while ((token = COM_Parse(&pScript)) != NULL && (token[0] != '}')) { if (strlen(params)) { // add a space between each param Q_strcat(params, sizeof (params), " "); } if (strrchr(token, ' ')) { // need to wrap this param in quotes since it has more than one word Q_strcat(params, sizeof (params), "\""); } Q_strcat(params, sizeof (params), token); if (strrchr(token, ' ')) { // need to wrap this param in quotes since it has mor Q_strcat(params, sizeof (params), "\""); } } } else // hackly precaching of custom characters if (!Q_stricmp(token, "spawnbot")) { // this is fairly indepth, so I'll move it to a separate function for readability G_Script_ParseSpawnbot(&pScript, params, MAX_INFO_STRING); } else { token = COM_ParseExt(&pScript, qfalse); for (i = 0; token[0]; ++i) { if (strlen(params)) { // add a space between each param Q_strcat(params, sizeof (params), " "); } if (i == 0) { // Special case: playsound's need to be cached on startup to prevent in-game pauses if (!Q_stricmp(action->actionString, "playsound")) { G_SoundIndex(token); } else if (!Q_stricmp(action->actionString, "changemodel")) { G_ModelIndex(token); } else if (buildScript && (!Q_stricmp(action->actionString, "mu_start") || !Q_stricmp(action->actionString, "mu_play") || !Q_stricmp(action->actionString, "mu_queue") || !Q_stricmp(action->actionString, "startcam")) && strlen(token)) { trap_SendServerCommand(-1, va("addToBuild %s\n", token)); } } if ((i == 0 || i == 1) && !Q_stricmp(action->actionString, "remapshader")) { G_ShaderIndex(token); } if (strrchr(token, ' ')) { // need to wrap this param in quotes since it has more than one word Q_strcat(params, sizeof (params), "\""); } Q_strcat(params, sizeof (params), token); if (strrchr(token, ' ')) { // need to wrap this param in quotes since it has more than one word Q_strcat(params, sizeof (params), "\""); } token = COM_ParseExt(&pScript, qfalse); } } if (strlen(params)) { // copy the params into the event curEvent->stack.items[curEvent->stack.numItems].params = G_Alloc(strlen(params) + 1); Q_strncpyz(curEvent->stack.items[curEvent->stack.numItems].params, params, strlen(params) + 1); } curEvent->stack.numItems++; if (curEvent->stack.numItems >= G_MAX_SCRIPT_STACK_ITEMS) { G_Error("G_Script_ScriptParse(): script exceeded G_MAX_SCRIPT_STACK_ITEMS (%d), line %d\n", G_MAX_SCRIPT_STACK_ITEMS, COM_GetCurrentParseLine()); } } numEventItems++; } else { // skip this character completely // TTimo gcc: suggest parentheses around assignment used as truth value while ((token = COM_Parse(&pScript)) != NULL) { if (!token[0]) { G_Error("G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine()); } else if (token[0] == '{') { bracketLevel++; } else if (token[0] == '}' && !--bracketLevel) { break; } } } } // alloc and copy the events into the gentity_t for this cast if (numEventItems > 0) { ent->scriptEvents = G_Alloc(sizeof (g_script_event_t) * numEventItems); memcpy(ent->scriptEvents, events, sizeof (g_script_event_t) * numEventItems); ent->numScriptEvents = numEventItems; } }
//WHITELIST FUNCTIONS void G_globalAddToWhitelist(gentity_t *ent, gentity_t *victim, char *who, char *reason, char *ip, char *guid) { whitelist_t *temp = G_Alloc(sizeof(whitelist_t)); char data[255]; G_Printf("Add whitelist called\n"); Q_strncpyz(temp->adminName, (G_isPlayerConnected(ent)) ? ent->client->pers.netname : "console", sizeof(temp->adminName)); Q_strncpyz(temp->playerName, (G_isPlayerConnected(victim)) ? victim->client->pers.netname : "UnnamedPlayer", sizeof(temp->playerName)); Q_strncpyz(temp->guid, (guid) ? guid : "", sizeof(temp->guid)); Q_strncpyz(temp->ip, (ip) ? ip : "", sizeof(temp->ip)); Q_strncpyz(temp->reason, (reason) ? reason : "", sizeof(temp->reason)); if (trap_mysql_runquery(va("INSERT HIGH_PRIORITY INTO whitelist" " (ip,guid,playerid,playername,adminid,adminname,reason) " " VALUES (\"%s\",\"%s\",\"%d\",\"%s\",\"%d\",\"%s\",\"%s\") ", temp->ip, temp->guid, (G_isPlayerConnected(victim) ? victim->client->pers.mysqlid : -1), (G_isPlayerConnected(victim) ? victim->client->pers.netname : "UnnamedPlayer"), (G_isPlayerConnected(ent) ? ent->client->pers.mysqlid : -1), (G_isPlayerConnected(ent) ? ent->client->pers.netname : "console"), temp->reason)) == qtrue) { trap_mysql_finishquery(); AP( va( "print \"^3%s:^7 have been added to white list by %s reason: %s \n\"", (G_isPlayerConnected(victim) ? victim->client->pers.netname : ip), (G_isPlayerConnected(ent)) ? ent->client->pers.netname : "console", reason)); G_LogPrintf("^3%s:^7 have been added to white list by %s reason: %s \n", (G_isPlayerConnected(victim) ? victim->client->pers.netname : ip), (G_isPlayerConnected(ent)) ? ent->client->pers.netname : "console", reason); if (trap_mysql_runquery(va("SELECT HIGH_PRIORITY id FROM whitelist ORDER BY id DESC LIMIT 1")) == qtrue) { if (trap_mysql_fetchrow() == qtrue) { trap_mysql_fetchfieldbyName("id", data, sizeof(data)); trap_mysql_finishquery(); temp->id = atoi(data); } else { G_LogPrintf("WARNING: Couldnt insert whitelist to database\n"); if (level.whitelist) { temp->id = level.globals->id + 1; } else { temp->id = 1; } } } } temp->next = level.whitelist; level.whitelist = temp; }