Пример #1
0
/*
============
AIChar_AIScript_AlertEntity

  triggered spawning, called from AI scripting
============
*/
void AIChar_AIScript_AlertEntity( gentity_t *ent ) {
    vec3_t mins, maxs;
    int numTouch, touch[10], i;
    cast_state_t    *cs;

    if ( !ent->aiInactive ) {
        return;
    }

    cs = AICast_GetCastState( ent->s.number );

    // if the current bounding box is invalid, then wait
    VectorAdd( ent->r.currentOrigin, ent->r.mins, mins );
    VectorAdd( ent->r.currentOrigin, ent->r.maxs, maxs );
    trap_UnlinkEntity( ent );

    numTouch = trap_EntitiesInBox( mins, maxs, touch, 10 );

    // check that another client isn't inside us
    if ( numTouch ) {
        for ( i = 0; i < numTouch; i++ ) {
            // RF, note we should only check against clients since zombies need to spawn inside func_explosive (so they dont clip into view after it explodes)
            if ( g_entities[touch[i]].client && g_entities[touch[i]].r.contents == CONTENTS_BODY ) {
                //if (g_entities[touch[i]].r.contents & MASK_PLAYERSOLID)
                break;
            }
        }
        if ( i == numTouch ) {
            numTouch = 0;
        }
    }

    if ( numTouch ) {
        // invalid location
        cs->aiFlags |= AIFL_WAITINGTOSPAWN;
        return;
    }

    // RF, has to disable this so I could test some maps which have erroneously placed alertentity calls
    //ent->AIScript_AlertEntity = NULL;
    cs->aiFlags &= ~AIFL_WAITINGTOSPAWN;
    ent->aiInactive = qfalse;
    trap_LinkEntity( ent );

    // trigger a spawn script event
    AICast_ScriptEvent( AICast_GetCastState( ent->s.number ), "spawn", "" );
    // make it think so we update animations/angles
    AICast_Think( ent->s.number, (float)FRAMETIME / 1000 );
    cs->lastThink = level.time;
    AICast_UpdateInput( cs, FRAMETIME );
    trap_BotUserCommand( cs->bs->client, &( cs->lastucmd ) );
}
Пример #2
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;
}