/*------------------------------------------------------------------- Procedure : AI Do a Sacn and find a target... Input : ENEMY * Enemy Output : Nothing -------------------------------------------------------------------*/ void AI_DO_SCAN( register ENEMY * Enemy ) { OBJECT * TObject; // Scan for target Tinfo->Pos.x = Enemy->Object.Pos.x; Tinfo->Pos.y = Enemy->Object.Pos.y; Tinfo->Pos.z = Enemy->Object.Pos.z; Tinfo->Group = Enemy->Object.Group; Tinfo->Nearest = BIGDISTANCE; Tinfo->TFlags = 0; Tinfo->SObject = &Enemy->Object; Tinfo->TObject = NULL; SET_TARGET_PLAYERS; AI_GetDistToNearestTarget( Enemy ); if( Tinfo->TFlags & _TARGET_PLAYERS ) { TObject = Tinfo->TObject; if( AI_InViewCone( &Enemy->Object.Pos , &Enemy->Object.Mat , &TObject->Pos, Enemy->Viewcone ) || ( ( Enemy->LastDistance <= EnemyTypes[Enemy->Type].Behave.HearRange) && TObject->Noise ) ) { if( AI_ClearLOS( &Enemy->Object.Pos , Enemy->Object.Group , &TObject->Pos ) ) { Enemy->TShip = Tinfo->TObject; } } } }
/*=================================================================== Procedure : TURRET Fire At Target.. Input : ENEMY * Enemy Output : Nothing ===================================================================*/ void AI_TURRET_FIREATTARGET( register ENEMY * Enemy ) { OBJECT * TObject; TObject = (OBJECT*) Enemy->TShip; if( (Enemy->Type != ENEMY_MissileTurret) ) { if( Enemy->Object.Animating && !(Enemy->Object.CurAnimSeq == TURRETSEQ_Fire) ) { return; } }else{ if( Enemy->Object.Animating && (Enemy->Object.CurAnimSeq == TURRETSEQ_Opening ) ) { }else{ if( !Enemy->Object.Animating ) { SetCurAnimSeq( TURRETSEQ_Open, &Enemy->Object ); } } } AI_THINK( Enemy , true , true ); // Is it time to validate target ? if ( Enemy->Timer == 0.0F ) { if( !( Enemy->AIFlags & AI_ANYPLAYERINRANGE ) || !AI_ClearLOS( &Enemy->Object.Pos ,Enemy->Object.Group , &TObject->Pos ) ) { Enemy->AIFlags &= ~AI_ICANSEEPLAYER; SetCurAnimSeq( TURRETSEQ_Closing, &Enemy->Object ); AI_SetSCAN( Enemy ); return; } Enemy->Timer = RESET_VALIDATE_TIME + (float) Random_Range( (u_int16_t) RESET_VALIDATE_TIME ); }else{ Enemy->Timer -= framelag; if( Enemy->Timer < 0.0F ) Enemy->Timer = 0.0F; } Enemy->AIFlags |= AI_ICANSEEPLAYER; AI_UPDATEGUNS( Enemy ); }
/*------------------------------------------------------------------- Procedure : AI for a turret while its SCANNING.. Output : ENEMY * Enemy Output : Nothing -------------------------------------------------------------------*/ void AI_TURRET_SCAN( register ENEMY * Enemy ) { OBJECT * TObject; Enemy->Timer -= framelag; if( Enemy->Object.Animating ) { return; } // Scan for target if ( Enemy->Timer <= 0.0F ) { AI_THINK( Enemy , TRUE , TRUE ); if( Enemy->AIFlags & AI_ANYPLAYERINRANGE ) { SET_TARGET_PLAYERS; AI_GetDistToNearestTarget( Enemy ); switch( Tinfo->TFlags ) { case _TARGET_PLAYERS: TObject = Tinfo->TObject; if( AI_InViewCone( &Enemy->Object.Pos ,&Enemy->Object.Mat , &TObject->Pos, Enemy->Viewcone ) ) { if( AI_ClearLOS( &Enemy->Object.Pos, Enemy->Object.Group , &TObject->Pos ) ) { Enemy->AIFlags |= AI_ICANSEEPLAYER; SetCurAnimSeq( TURRETSEQ_Opening, &Enemy->Object ); Enemy->TShip = TObject; AI_SetFIREATTARGET( Enemy ); } } break; default: // Switch to AIMODE_IDLE Enemy->Object.AI_Mode = AIMODE_IDLE; Enemy->Timer = RESET_IDLE_TIME; break; } }else{ Enemy->Object.AI_Mode = AIMODE_IDLE; Enemy->Timer = RESET_IDLE_TIME; } } }
/*------------------------------------------------------------------- Procedure : AIR Scan for a Target Input : ENEMY * Enemy Output : Nothing -------------------------------------------------------------------*/ void AI_AIR_SCAN( register ENEMY * Enemy ) { OBJECT * TObject; float dist; // Scan for target Tinfo->Flags = 0; SET_TARGET_PLAYERS; AI_GetDistToNearestTarget( Enemy ); if( Tinfo->TFlags == _TARGET_PLAYERS ) { TObject = Tinfo->TObject; dist = DistanceVector2Vector( &Enemy->Object.Pos , &Tinfo->Pos ) + SoundInfo[Enemy->Object.Group][TObject->Group]; if( AI_InViewCone( &Enemy->Object.Pos , &Enemy->Object.Mat , &TObject->Pos, Enemy->Viewcone ) || ( (dist <= EnemyTypes[Enemy->Type].Behave.HearRange) && TObject->Noise ) ) { if( AI_ClearLOS( &Enemy->Object.Pos , Enemy->Object.Group , &TObject->Pos ) ) { Enemy->TShip = Tinfo->TObject; AI_SetMOVETOTARGET( Enemy ); return; }else{ if( Enemy->TShip && TObject->NearestNode ) { Enemy->TShip = Tinfo->TObject; Enemy->TNode = (void*) WhichNode( Enemy->Object.NodeNetwork , Enemy->Object.NearestNode , TObject->NearestNode ); AI_SetMOVETOTARGET( Enemy ); return; } } } } // Switch to AIMODE_IDLE AI_SetIDLE( Enemy ); }
/*------------------------------------------------------------------- Procedure : Exogenon Scan Input : ENEMY * Enemy Output : Nothing -------------------------------------------------------------------*/ void AI_EXOGENON_SCAN( register ENEMY * Enemy ) { ExogenonAim( Enemy ); Enemy->Object.AnimSpeed = 2.0F; if( Enemy->Object.Animating ) { return; } if( !AI_ClearLOS( &Enemy->Object.Pos,Enemy->Object.Group, &Ships[WhoIAm].Object.Pos ) ) { Enemy->Object.AI_Mode = AIMODE_EXOGENON_MOVEUP; SetCurAnimSeq( EXOGENONSEQ_Move_Up, &Enemy->Object ); ExogenonFireLeftRight( Enemy ); return; } Enemy->Object.AI_Mode = AIMODE_EXOGENON_FIRE; SetCurAnimSeq( EXOGENONSEQ_Fire, &Enemy->Object ); Enemy->Timer = 60.0F * 2.5F; }