void trigger_aidoor_stayopen( gentity_t * ent, gentity_t * other, trace_t * trace ) { gentity_t *door; // FIXME: port this code over to moving doors (use MOVER_POSx instead of MOVER_POSxROTATE) if ( other->client && other->health > 0 ) { if ( !ent->target || !( strlen( ent->target ) ) ) { // ent->target of "" will crash game in Q_stricmp() // FIXME: commented out so it can be fixed // G_Printf( "trigger_aidoor at loc %s does not have a target door\n", vtos (ent->s.origin) ); return; } door = G_Find( NULL, FOFS( targetname ), ent->target ); if ( !door ) { // FIXME: commented out so it can be fixed // G_Printf( "trigger_aidoor at loc %s does not have a target door\n", vtos (ent->s.origin) ); return; } if ( door->moverState == MOVER_POS2ROTATE ) { // door is in open state waiting to close keep it open door->nextthink = level.time + door->wait + 3000; } // Ridah, door isn't ready, find a free ai_marker, and wait there until it's open if ( other->r.svFlags & SVF_CASTAI ) { if ( door->key ) { // we dont have keys, so assume we are not trying to get through this door return; } G_Activate( door, other ); // if the door isn't currently opening for us, we should move out the way // Ridah, had to change this, since it was causing AI to wait at door when the door is open, and won't close because they are sitting on the aidoor brush //if (!(door->activator == other && (door->moverState == MOVER_1TO2ROTATE || door->moverState == MOVER_POS2ROTATE))) { // NOTE TTimo: SP has a slightly different test? (this is prolly outdated) if ( !( ( door->activator == other ) && ( door->moverState != MOVER_POS1 ) && ( door->moverState != MOVER_POS1ROTATE ) ) && ( door->moverState != MOVER_POS2ROTATE ) && ( door->moverState != MOVER_POS2 ) ) { // if we aren't already heading for an ai_marker, look for one we can go to AICast_AIDoor_Touch( other, ent, door ); } } } }
/* ================ AICast_EvaluatePmove Avoidance after the event (leaders instruct AI's to get out the way, AI's instruct other non-moving AI's to get out the way) ================ */ void AICast_EvaluatePmove( int clientnum, pmove_t *pm ) { cast_state_t *cs, *ocs; int i, ent; bot_goal_t ogoal; //vec3_t pos, dir; cs = AICast_GetCastState( clientnum ); // make sure we are using the right AAS data for this entity (one's that don't get set will default to the player's AAS data) trap_AAS_SetCurrentWorld( cs->aasWorldIndex ); // NOTE: this is only enabled for real clients, so their followers get out of their way //if (cs->bs) // return; // look through the touchent's to see if we've bumped into something we should avoid, or react to for ( i = 0; i < pm->numtouch; i++ ) { // mark the time, so they can deal with the obstruction in their own think functions cs->blockedTime = level.time; if ( pm->touchents[i] == pm->ps->groundEntityNum ) { continue; } // if they are an AI Cast, inform them of our disposition, and hope that they are reasonable // enough to assist us in our desire to move beyond our current position if ( pm->touchents[i] < aicast_maxclients ) { if ( !AICast_EntityVisible( cs, pm->touchents[i], qtrue ) ) { continue; } // if we are inspecting the body, abort if we touch anything if ( cs->bs && cs->bs->enemy >= 0 && g_entities[cs->bs->enemy].health <= 0 ) { cs->bs->enemy = -1; } // anything we touch, should see us AICast_UpdateVisibility( &g_entities[pm->touchents[i]], &g_entities[cs->entityNum], qfalse, qtrue ); ocs = AICast_GetCastState( pm->touchents[i] ); if ( ( ocs->bs ) && ( !( ocs->aiFlags & AIFL_NOAVOID ) ) && ( ( ocs->leaderNum == cs->entityNum ) || ( VectorLength( ocs->bs->velocity ) < 5 ) ) && ( ocs->obstructingTime < ( level.time + 100 ) ) ) { // if they are moving away from us already, let them go if ( VectorLength( ocs->bs->cur_ps.velocity ) > 10 ) { vec3_t v1, v2; VectorSubtract( ocs->bs->origin, g_entities[clientnum].client->ps.velocity, v2 ); VectorNormalize( v2 ); VectorNormalize2( ocs->bs->cur_ps.velocity, v1 ); if ( DotProduct( v1, v2 ) > 0.0 ) { continue; } } if ( ocs->leaderNum >= 0 ) { VectorCopy( g_entities[ocs->leaderNum].r.currentOrigin, ogoal.origin ); ogoal.areanum = BotPointAreaNum( ogoal.origin ); ogoal.entitynum = ocs->leaderNum; if ( ocs->bs && AICast_GetAvoid( ocs, &ogoal, ocs->obstructingPos, qfalse, cs->entityNum ) ) { // give them time to move somewhere else ocs->obstructingTime = level.time + 1000; } } else { if ( ocs->bs && AICast_GetAvoid( ocs, NULL, ocs->obstructingPos, qfalse, cs->entityNum ) ) { // give them time to move somewhere else ocs->obstructingTime = level.time + 1000; } } } } else if ( cs->bs ) { // if we are blocked by a brush entity, see if we can activate it ent = pm->touchents[i]; if ( g_entities[ent].s.modelindex > 0 && g_entities[ent].s.eType == ET_MOVER ) { //find the bsp entity which should be activated in order to remove //the blocking entity if ( !g_entities[ent].isProp && Q_stricmp( g_entities[ent].classname, "func_static" ) && Q_stricmp( g_entities[ent].classname, "func_button" ) && Q_stricmp( g_entities[ent].classname, "func_tram" ) ) { G_Activate( &g_entities[ent], &g_entities[cs->entityNum] ); } } } } }