Exemplo n.º 1
0
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);
	}
}
Exemplo n.º 2
0
/*
==================
BotAIStartFrame
==================
*/
int BotAIStartFrame(int time) {
	int i;
	gentity_t	*ent;
	bot_entitystate_t state;
	int elapsed_time, thinktime;
	static int local_time;
	static int botlib_residual;
	static int lastbotthink_time;

	G_CheckBotSpawn();

	trap_Cvar_Update(&bot_rocketjump);
	trap_Cvar_Update(&bot_grapple);
	trap_Cvar_Update(&bot_fastchat);
	trap_Cvar_Update(&bot_nochat);
	trap_Cvar_Update(&bot_testrchat);
	trap_Cvar_Update(&bot_thinktime);
	trap_Cvar_Update(&bot_memorydump);
	trap_Cvar_Update(&bot_saveroutingcache);
	trap_Cvar_Update(&bot_pause);
	trap_Cvar_Update(&bot_report);
	trap_Cvar_Update(&bot_droppedweight);
	trap_Cvar_Update(&bot_offhandgrapple);
	trap_Cvar_Update(&bot_shownodechanges);
	trap_Cvar_Update(&bot_showteamgoals);
	trap_Cvar_Update(&bot_reloadcharacters);

	BotUpdateInfoConfigStrings();

	if (bot_pause.integer) {
		// execute bot user commands every frame
		for( i = 0; i < level.maxplayers; i++ ) {
			if( !botstates[i] || !botstates[i]->inuse ) {
				continue;
			}
			if( g_entities[i].player->pers.connected != CON_CONNECTED ) {
				continue;
			}
			botstates[i]->lastucmd.forwardmove = 0;
			botstates[i]->lastucmd.rightmove = 0;
			botstates[i]->lastucmd.upmove = 0;
			botstates[i]->lastucmd.buttons = 0;
			botstates[i]->lastucmd.serverTime = time;
			trap_BotUserCommand(botstates[i]->playernum, &botstates[i]->lastucmd);
		}
		return qtrue;
	}

	if (bot_memorydump.integer) {
		trap_BotLibVarSet("memorydump", "1");
		trap_Cvar_SetValue("bot_memorydump", 0);
	}
	if (bot_saveroutingcache.integer) {
		trap_BotLibVarSet("saveroutingcache", "1");
		trap_Cvar_SetValue("bot_saveroutingcache", 0);
	}
	//check if bot interbreeding is activated
	BotInterbreeding();
	//cap the bot think time
	if (bot_thinktime.integer > 200) {
		trap_Cvar_SetValue("bot_thinktime", 200);
	}
	//if the bot think time changed we should reschedule the bots
	if (bot_thinktime.integer != lastbotthink_time) {
		lastbotthink_time = bot_thinktime.integer;
		BotScheduleBotThink();
	}

	elapsed_time = time - local_time;
	local_time = time;

	botlib_residual += elapsed_time;

	if (elapsed_time > bot_thinktime.integer) thinktime = elapsed_time;
	else thinktime = bot_thinktime.integer;

	// update the bot library
	if ( botlib_residual >= thinktime ) {
		botlib_residual -= thinktime;

		trap_BotLibStartFrame((float) time / 1000);

		if (!trap_AAS_Initialized()) return qfalse;

		//update entities in the botlib
		for (i = 0; i < MAX_GENTITIES; i++) {
			ent = &g_entities[i];
			ent->botvalid = qfalse;
			if (!ent->inuse) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
			if (!ent->r.linked) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
			if (ent->r.svFlags & SVF_NOCLIENT) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
			// do not update missiles
			if (ent->s.eType == ET_MISSILE && ent->s.weapon != WP_GRAPPLING_HOOK) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
			// do not update event only entities
			if (ent->s.eType > ET_EVENTS) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
#ifdef MISSIONPACK
			// never link prox mine triggers
			if (ent->s.contents == CONTENTS_TRIGGER) {
				if (ent->touch == ProximityMine_Trigger) {
					trap_BotLibUpdateEntity(i, NULL);
					continue;
				}
			}
#endif
			//
			ent->botvalid = qtrue;
			ent->update_time = trap_AAS_Time() - ent->ltime;
			ent->ltime = trap_AAS_Time();
			//
			memset(&state, 0, sizeof(bot_entitystate_t));
			//
			VectorCopy(ent->r.currentOrigin, state.origin);
			if (i < MAX_CLIENTS) {
				VectorCopy(ent->s.apos.trBase, state.angles);
			} else {
				VectorCopy(ent->r.currentAngles, state.angles);
			}
			VectorCopy( ent->r.absmin, state.absmins );
			VectorCopy( ent->r.absmax, state.absmaxs );
			state.type = ent->s.eType;
			state.flags = ent->s.eFlags;
			//
			if (ent->s.collisionType == CT_SUBMODEL) {
				state.solid = SOLID_BSP;
				//if the angles of the model changed
				if ( !VectorCompare( state.angles, ent->lastAngles ) ) {
					VectorCopy(state.angles, ent->lastAngles);
					state.relink = qtrue;
				}
			} else {
				state.solid = SOLID_BBOX;
				VectorCopy(state.angles, ent->lastAngles);
			}
			//previous frame visorigin
			VectorCopy( ent->visorigin, ent->lastvisorigin );
			//if the origin changed
			if ( !VectorCompare( state.origin, ent->visorigin ) ) {
				VectorCopy( state.origin, ent->visorigin );
				state.relink = qtrue;
			}
			//if the bounding box size changed
			if (!VectorCompare(ent->s.mins, ent->lastMins) ||
					!VectorCompare(ent->s.maxs, ent->lastMaxs))
			{
				VectorCopy( ent->s.mins, ent->lastMins );
				VectorCopy( ent->s.maxs, ent->lastMaxs );
				state.relink = qtrue;
			}
			//
			trap_BotLibUpdateEntity(i, &state);
		}

		BotAIRegularUpdate();
	}

	floattime = trap_AAS_Time();

	// execute scheduled bot AI
	for( i = 0; i < MAX_CLIENTS; i++ ) {
		if( !botstates[i] || !botstates[i]->inuse ) {
			continue;
		}
		//
		botstates[i]->botthink_residual += elapsed_time;
		//
		if ( botstates[i]->botthink_residual >= thinktime ) {
			botstates[i]->botthink_residual -= thinktime;

			if (!trap_AAS_Initialized()) return qfalse;

			if (g_entities[i].player->pers.connected == CON_CONNECTED) {
				BotAI(i, (float) thinktime / 1000);
			}
		}
	}


	// execute bot user commands every frame
	for( i = 0; i < MAX_CLIENTS; i++ ) {
		if( !botstates[i] || !botstates[i]->inuse ) {
			continue;
		}
		if( g_entities[i].player->pers.connected != CON_CONNECTED ) {
			continue;
		}

		BotUpdateInput(botstates[i], time, elapsed_time);
		trap_BotUserCommand(botstates[i]->playernum, &botstates[i]->lastucmd);
	}

	return qtrue;
}
Exemplo n.º 3
0
/*
==================
BotAIStartFrame
==================
*/
int BotAIStartFrame( int time ) {
	int i;
	gentity_t   *ent;
	bot_entitystate_t state;
	//entityState_t entitystate;
	//vec3_t mins = {-15, -15, -24}, maxs = {15, 15, 32};
	int elapsed_time, thinktime;
	static int local_time;
	static int botlib_residual;
	static int lastbotthink_time;

	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		G_CheckBotSpawn();
	}

	trap_Cvar_Update( &bot_rocketjump );
	trap_Cvar_Update( &bot_grapple );
	trap_Cvar_Update( &bot_fastchat );
	trap_Cvar_Update( &bot_nochat );
	trap_Cvar_Update( &bot_testrchat );
	trap_Cvar_Update( &bot_thinktime );
	// Ridah, set the default AAS world
	trap_AAS_SetCurrentWorld( 0 );
	trap_Cvar_Update( &memorydump );

	if ( memorydump.integer ) {
		trap_BotLibVarSet( "memorydump", "1" );
		trap_Cvar_Set( "memorydump", "0" );
	}

	//if the bot think time changed we should reschedule the bots
	if ( bot_thinktime.integer != lastbotthink_time ) {
		lastbotthink_time = bot_thinktime.integer;
		BotScheduleBotThink();
	}

	elapsed_time = time - local_time;
	local_time = time;

	botlib_residual += elapsed_time;

	if ( elapsed_time > bot_thinktime.integer ) {
		thinktime = elapsed_time;
	} else { thinktime = bot_thinktime.integer;}

	// update the bot library
	if ( botlib_residual >= thinktime ) {
		botlib_residual -= thinktime;

		trap_BotLibStartFrame( (float) time / 1000 );

		// Ridah, only check the default world
		trap_AAS_SetCurrentWorld( 0 );

		if ( !trap_AAS_Initialized() ) {
			return BLERR_NOERROR;
		}

		//update entities in the botlib
		for ( i = 0; i < MAX_GENTITIES; i++ ) {

			// Ridah, in single player, we only need client entity information
			if ( g_gametype.integer == GT_SINGLE_PLAYER && i > level.maxclients ) {
				break;
			}

			ent = &g_entities[i];
			if ( !ent->inuse ) {
				continue;
			}
			if ( !ent->r.linked ) {
				continue;
			}
			if ( ent->r.svFlags & SVF_NOCLIENT ) {
				continue;
			}
			//
			memset( &state, 0, sizeof( bot_entitystate_t ) );
			//
			VectorCopy( ent->r.currentOrigin, state.origin );
			VectorCopy( ent->r.currentAngles, state.angles );
			VectorCopy( ent->s.origin2, state.old_origin );
			VectorCopy( ent->r.mins, state.mins );
			VectorCopy( ent->r.maxs, state.maxs );
			state.type = ent->s.eType;
			state.flags = ent->s.eFlags;
			if ( ent->r.bmodel ) {
				state.solid = SOLID_BSP;
			} else { state.solid = SOLID_BBOX;}
			state.groundent = ent->s.groundEntityNum;
			state.modelindex = ent->s.modelindex;
			state.modelindex2 = ent->s.modelindex2;
			state.frame = ent->s.frame;
			//state.event = ent->s.event;
			//state.eventParm = ent->s.eventParm;
			state.powerups = ent->s.powerups;
			state.legsAnim = ent->s.legsAnim;
			state.torsoAnim = ent->s.torsoAnim;
//			state.weapAnim = ent->s.weapAnim;	//----(SA)
//----(SA)	didn't want to comment in as I wasn't sure of any implications of changing the aas_entityinfo_t and bot_entitystate_t structures.
			state.weapon = ent->s.weapon;
			/*
			if (!BotAI_GetEntityState(i, &entitystate)) continue;
			//
			memset(&state, 0, sizeof(bot_entitystate_t));
			//
			VectorCopy(entitystate.pos.trBase, state.origin);
			VectorCopy(entitystate.angles, state.angles);
			VectorCopy(ent->s.origin2, state.old_origin);
			//VectorCopy(ent->r.mins, state.mins);
			//VectorCopy(ent->r.maxs, state.maxs);
			state.type = entitystate.eType;
			state.flags = entitystate.eFlags;
			if (ent->r.bmodel) state.solid = SOLID_BSP;
			else state.solid = SOLID_BBOX;
			state.modelindex = entitystate.modelindex;
			state.modelindex2 = entitystate.modelindex2;
			state.frame = entitystate.frame;
			state.event = entitystate.event;
			state.eventParm = entitystate.eventParm;
			state.powerups = entitystate.powerups;
			state.legsAnim = entitystate.legsAnim;
			state.torsoAnim = entitystate.torsoAnim;
			state.weapon = entitystate.weapon;
			*/
			//
			trap_BotLibUpdateEntity( i, &state );
		}

		BotAIRegularUpdate();

	}

	// Ridah, in single player, don't need bot's thinking
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		return BLERR_NOERROR;
	}

	// execute scheduled bot AI
	for ( i = 0; i < MAX_CLIENTS; i++ ) {
		if ( !botstates[i] || !botstates[i]->inuse ) {
			continue;
		}
		// Ridah
		if ( g_entities[i].r.svFlags & SVF_CASTAI ) {
			continue;
		}
		// done.
		//
		botstates[i]->botthink_residual += elapsed_time;
		//
		if ( botstates[i]->botthink_residual >= thinktime ) {
			botstates[i]->botthink_residual -= thinktime;

			if ( !trap_AAS_Initialized() ) {
				return BLERR_NOERROR;
			}

			if ( g_entities[i].client->pers.connected == CON_CONNECTED ) {
				BotAI( i, (float) thinktime / 1000 );
			}
		}
	}


	// execute bot user commands every frame
	for ( i = 0; i < MAX_CLIENTS; i++ ) {
		if ( !botstates[i] || !botstates[i]->inuse ) {
			continue;
		}
		// Ridah
		if ( g_entities[i].r.svFlags & SVF_CASTAI ) {
			continue;
		}
		// done.
		if ( g_entities[i].client->pers.connected != CON_CONNECTED ) {
			continue;
		}

		BotUpdateInput( botstates[i], time );
		trap_BotUserCommand( botstates[i]->client, &botstates[i]->lastucmd );
	}

	return BLERR_NOERROR;
}
Exemplo n.º 4
0
/*
==================
BotAIStartFrame
==================
*/
int BotAIStartFrame(int time) {
	int i;
	gentity_t	*ent;
	bot_entitystate_t state;
	int elapsed_time, thinktime;
	static int local_time;
	static int botlib_residual;
	static int lastbotthink_time;

	G_CheckBotSpawn();

	trap_Cvar_Update(&bot_rocketjump);
	trap_Cvar_Update(&bot_grapple);
	trap_Cvar_Update(&bot_fastchat);
	trap_Cvar_Update(&bot_nochat);
	trap_Cvar_Update(&bot_testrchat);
	trap_Cvar_Update(&bot_thinktime);
	trap_Cvar_Update(&bot_memorydump);
	trap_Cvar_Update(&bot_saveroutingcache);
	trap_Cvar_Update(&bot_pause);
	trap_Cvar_Update(&bot_report);

	if (bot_report.integer) {
//		BotTeamplayReport();
//		trap_Cvar_Set("bot_report", "0");
		BotUpdateInfoConfigStrings();
	}

	if (bot_pause.integer) {
		// execute bot user commands every frame
		for( i = 0; i < MAX_CLIENTS; i++ ) {
			if( !botstates[i] || !botstates[i]->inuse ) {
				continue;
			}
			if( g_entities[i].client->pers.connected != CON_CONNECTED ) {
				continue;
			}
			botstates[i]->lastucmd.forwardmove = 0;
			botstates[i]->lastucmd.rightmove = 0;
			botstates[i]->lastucmd.upmove = 0;
			botstates[i]->lastucmd.buttons = 0;
			botstates[i]->lastucmd.serverTime = time;
			trap_BotUserCommand(botstates[i]->client, &botstates[i]->lastucmd);
		}
		return qtrue;
	}

	if (bot_memorydump.integer) {
		trap_BotLibVarSet("memorydump", "1");
		trap_Cvar_Set("bot_memorydump", "0");
	}
	if (bot_saveroutingcache.integer) {
		trap_BotLibVarSet("saveroutingcache", "1");
		trap_Cvar_Set("bot_saveroutingcache", "0");
	}
	//check if bot interbreeding is activated
	BotInterbreeding();
	//cap the bot think time
	if (bot_thinktime.integer > 200) {
		trap_Cvar_Set("bot_thinktime", "200");
	}
	//if the bot think time changed we should reschedule the bots
	if (bot_thinktime.integer != lastbotthink_time) {
		lastbotthink_time = bot_thinktime.integer;
		BotScheduleBotThink();
	}

	elapsed_time = time - local_time;
	local_time = time;

	botlib_residual += elapsed_time;

	if (elapsed_time > bot_thinktime.integer) thinktime = elapsed_time;
	else thinktime = bot_thinktime.integer;

	// update the bot library
	if ( botlib_residual >= thinktime ) {
		botlib_residual -= thinktime;

		trap_BotLibStartFrame((float) time / 1000);

		if (!trap_AAS_Initialized()) return qfalse;

		//update entities in the botlib
		for (i = 0; i < MAX_GENTITIES; i++) {
			ent = &g_entities[i];
			if (!ent->inuse) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
			if (!ent->r.linked) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
			if (ent->r.svFlags & SVF_NOCLIENT) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
			// do not update missiles
			if (ent->s.eType == ET_MISSILE && ent->s.weapon != WP_GRAPPLING_HOOK) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
			// do not update event only entities
			if (ent->s.eType > ET_EVENTS) {
				trap_BotLibUpdateEntity(i, NULL);
				continue;
			}
#if 1  //def MPACK
			// never link prox mine triggers
			if (ent->r.contents == CONTENTS_TRIGGER) {
				if (ent->touch == ProximityMine_Trigger) {
					trap_BotLibUpdateEntity(i, NULL);
					continue;
				}
			}
#endif
			//
			memset(&state, 0, sizeof(bot_entitystate_t));
			//
			VectorCopy(ent->r.currentOrigin, state.origin);
			if (i < MAX_CLIENTS) {
				VectorCopy(ent->s.apos.trBase, state.angles);
			} else {
				VectorCopy(ent->r.currentAngles, state.angles);
			}
			VectorCopy(ent->s.origin2, state.old_origin);
			VectorCopy(ent->r.mins, state.mins);
			VectorCopy(ent->r.maxs, state.maxs);
			state.type = ent->s.eType;
			state.flags = ent->s.eFlags;
			if (ent->r.bmodel) state.solid = SOLID_BSP;
			else state.solid = SOLID_BBOX;
			state.groundent = ent->s.groundEntityNum;
			state.modelindex = ent->s.modelindex;
			state.modelindex2 = ent->s.modelindex2;
			state.frame = ent->s.frame;
			state.event = ent->s.event;
			state.eventParm = ent->s.eventParm;
			state.powerups = ent->s.powerups;
			state.legsAnim = ent->s.legsAnim;
			state.torsoAnim = ent->s.torsoAnim;
			state.weapon = ent->s.weapon;
			//
			trap_BotLibUpdateEntity(i, &state);
		}

		BotAIRegularUpdate();
	}

	floattime = trap_AAS_Time();

	// execute scheduled bot AI
	for( i = 0; i < MAX_CLIENTS; i++ ) {
		if( !botstates[i] || !botstates[i]->inuse ) {
			continue;
		}
		//
		botstates[i]->botthink_residual += elapsed_time;
		//
		if ( botstates[i]->botthink_residual >= thinktime ) {
			botstates[i]->botthink_residual -= thinktime;

			if (!trap_AAS_Initialized()) return qfalse;

			if (g_entities[i].client->pers.connected == CON_CONNECTED) {
				BotAI(i, (float) thinktime / 1000);
			}
		}
	}


	// execute bot user commands every frame
	for( i = 0; i < MAX_CLIENTS; i++ ) {
		if( !botstates[i] || !botstates[i]->inuse ) {
			continue;
		}
		if( g_entities[i].client->pers.connected != CON_CONNECTED ) {
			continue;
		}

		BotUpdateInput(botstates[i], time, elapsed_time);
		trap_BotUserCommand(botstates[i]->client, &botstates[i]->lastucmd);
	}

	return qtrue;
}
Exemplo n.º 5
0
/*
============
AICast_StartServerFrame

  Do movements, sighting, etc
============
*/
void AICast_StartServerFrame( int time ) {
	int i, elapsed, count, clCount;
	cast_state_t    *cs;
	int castcount;
	static int lasttime;
	static vmCvar_t aicast_disable;
	gentity_t *ent;
	cast_state_t *pcs;
//	int		oldLegsTimer;

	if ( trap_Cvar_VariableIntegerValue( "savegame_loading" ) ) {
		return;
	}

	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		return;
	}

	if ( saveGamePending ) {
		return;
	}

	// if waiting at intermission, don't think
	if ( strlen( g_missionStats.string ) > 1 ) {
		return;
	}

	if ( !aicast_disable.handle ) {
		trap_Cvar_Register( &aicast_disable, "aicast_disable", "0", CVAR_CHEAT );
	} else
	{
		trap_Cvar_Update( &aicast_disable );
		if ( aicast_disable.integer ) {
			return;
		}
	}

	trap_Cvar_Update( &aicast_debug );

	// no need to think during the intermission
	if ( level.intermissiontime ) {
		return;
	}
	//
	// make sure the AAS gets updated
	trap_BotLibStartFrame( (float) time / 1000 );
	//
	//
	elapsed = time - lasttime;
	if ( elapsed == 0 ) {
		return;         // no time has elapsed
	}

	pcs = AICast_GetCastState( 0 );

//G_Printf( "AI startserverframe: %i\n", time );

	if ( elapsed < 0 ) {
		elapsed = 0;
		lasttime = time;
	}
	// don't let the framerate drop below 10
	if ( elapsed > 100 ) {
		elapsed = 100;
	}
	//
	// process player's current script if it exists
	AICast_ScriptRun( AICast_GetCastState( 0 ), qfalse );
	//
	AICast_SightUpdate( (int)( (float)SIGHT_PER_SEC * ( (float)elapsed / 1000 ) ) );
	//
	count = 0;
	castcount = 0;
	clCount = 0;
	ent = g_entities;
	//
	//update the AI characters
	// TTimo gcc: left-hand operand of comma expression has no effect
	// initial line: for (i = 0; i < aicast_maxclients, clCount < level.numPlayingClients; i++, ent++)
	for ( i = 0; ( i < aicast_maxclients ) && ( clCount < level.numPlayingClients ) ; i++, ent++ )
	{
		if ( ent->client ) {
			clCount++;
		}
		//
		cs = AICast_GetCastState( i );
		// is this a cast AI?
		if ( cs->bs ) {
			if ( ent->aiInactive == qfalse && ent->inuse ) {
				//
				elapsed = level.time - cs->lastMoveThink;
				//
				// optimization, if they're not in the player's PVS, and they aren't trying to move, then don't bother thinking
				if (    ( ( ent->health > 0 ) && ( elapsed > 300 ) )
						||  ( g_entities[0].client && g_entities[0].client->cameraPortal )
						||  ( cs->vislist[0].visible_timestamp == cs->vislist[0].lastcheck_timestamp )
						||  ( pcs->vislist[cs->entityNum].visible_timestamp == pcs->vislist[cs->entityNum].lastcheck_timestamp )
						||  ( VectorLength( ent->client->ps.velocity ) > 0 )
						||  ( cs->bs->lastucmd.forwardmove || cs->bs->lastucmd.rightmove || cs->bs->lastucmd.upmove > 0 || cs->bs->lastucmd.buttons || cs->bs->lastucmd.wbuttons )
						||  ( trap_InPVS( cs->bs->origin, g_entities[0].s.pos.trBase ) ) ) { // do pvs check last, since it's the most expensive to call
//					oldLegsTimer = ent->client->ps.legsTimer;
					//
					// send it's movement commands
					//
					serverTime = time;
					AICast_UpdateInput( cs, elapsed );
					trap_BotUserCommand( cs->bs->client, &( cs->bs->lastucmd ) );
					cs->lastMoveThink = level.time;
					//
					// check for anim changes that may require us to stay still
					//
/*					if (oldLegsTimer != ent->client->ps.legsTimer) {
						// dont move until they are finished
						if (cs->castScriptStatus.scriptNoMoveTime < level.time + ent->client->ps.legsTimer) {
							cs->castScriptStatus.scriptNoMoveTime = level.time + ent->client->ps.legsTimer;
						}
					}
*/              }
			} else {
				trap_UnlinkEntity( ent );
			}
			//
			// see if we've checked all cast AI's
			if ( ++castcount >= numcast ) {
				break;
			}
		}
	}
	//
	lasttime = time;
}
Exemplo n.º 6
0
void AICast_StartFrame( int time ) {
	int i, elapsed, count, clCount;
	cast_state_t    *cs;
	int castcount;
	static int lasttime;
	static vmCvar_t aicast_disable;
	gentity_t *ent;

	if ( trap_Cvar_VariableIntegerValue( "savegame_loading" ) ) {
		return;
	}

	if ( saveGamePending ) {
		return;
	}

	// if waiting at intermission, don't think
	if ( strlen( g_missionStats.string ) > 1 ) {
		return;
	}

	if ( !aicast_disable.handle ) {
		trap_Cvar_Register( &aicast_disable, "aicast_disable", "0", CVAR_CHEAT );
	} else
	{
		trap_Cvar_Update( &aicast_disable );
		if ( aicast_disable.integer ) {
			return;
		}
	}

	trap_Cvar_Update( &aicast_debug );
	trap_Cvar_Update( &aicast_debugname );
	trap_Cvar_Update( &aicast_scripts );

	// no need to think during the intermission
	if ( level.intermissiontime ) {
		return;
	}
	//
	// make sure the AAS gets updated
	trap_BotLibStartFrame( (float) time / 1000 );
	//
	//
	elapsed = time - lasttime;
	if ( elapsed == 0 ) {
		return;         // no time has elapsed
	}

//G_Printf( "AI startframe: %i\n", time );

	if ( elapsed < 0 ) {
		elapsed = 0;
		lasttime = time;
	}
	// don't let the framerate drop below 10
	if ( elapsed > 100 ) {
		elapsed = 100;
	}
	//AICast_SightUpdate( (int)((float)SIGHT_PER_SEC * ((float)elapsed / 1000)) );
	//
	count = 0;
	castcount = 0;
	clCount = 0;
	ent = g_entities;
	//
	//update the AI characters
	// TTimo gcc: left-hand operand of comma expression has no effect
	// initial line was: for (i = 0; i < aicast_maxclients, clCount < level.numPlayingClients; i++, ent++)
	for ( i = 0; ( i < aicast_maxclients ) && ( clCount < level.numPlayingClients ) ; i++, ent++ )
	{
		if ( ent->client ) {
			clCount++;
		}
		//
		cs = AICast_GetCastState( i );
		// is this a cast AI?
		if ( cs->bs ) {
			if ( ent->inuse ) {
				if ( ent->aiInactive == qfalse ) {
					//
					elapsed = time - cs->lastThink;
					//
					// if they're moving/firing think every frame
					if ( ( elapsed >= 50 ) &&
						 (   (   (   ( !VectorCompare( ent->client->ps.velocity, vec3_origin ) ) ||
									 ( ent->client->buttons ) ||
									 ( elapsed >= aicast_thinktime ) ) &&
								 ( count <= aicast_maxthink ) ) ||
							 ( elapsed >= aicast_thinktime * 2 ) ) ) {
						// make it think now
						AICast_Think( i, (float)elapsed / 1000 );
						cs->lastThink = time;
						//
						count++;
					}
					// check for any debug info updates
					AICast_DebugFrame( cs );
				} else if ( cs->aiFlags & AIFL_WAITINGTOSPAWN ) {
					// check f the space is clear yet
					ent->AIScript_AlertEntity( ent );
				}
			} else {
				trap_UnlinkEntity( ent );
			}
			//
			// see if we've checked all cast AI's
			if ( ++castcount >= numcast ) {
				break;
			}
		}
	}
	//
	lasttime = time;
}