Пример #1
0
/*===================================================================
	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 );
}
Пример #2
0
/*-------------------------------------------------------------------
    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;
        }
    }
}
Пример #3
0
/*-------------------------------------------------------------------
    Procedure   :   Exogenon Idle
    Input       :   ENEMY * Enemy
    Output      :   Nothing
-------------------------------------------------------------------*/
void AI_EXOGENON_IDLE( register ENEMY * Enemy )
{
    int i;
    int startpos = 0;
    float   Distance = 0.0F;
    AI_THINK( Enemy , TRUE , TRUE );

    if( Enemy->Object.CurAnimSeq != EXOGENONSEQ_Stop_Up )
    {
        SetCurAnimSeq( EXOGENONSEQ_Stop_Up, &Enemy->Object );
        return;
    }
    
    Enemy->Object.Pos = Exogenon_StartPos[0];
    Enemy->Object.Pos.y += 256.0F * 10.0F;
    if( !(Enemy->AIFlags & AI_ANYPLAYERINRANGE) )
        return;

    if( Enemy->Timer )
    {
        Enemy->Timer -= framelag;
        if( Enemy->Timer <= 0.0F )
        {
            Enemy->Timer = 0.0F;
        }
        return;
    }

    startpos = Random_Range( (uint16) Exogenon_Num_StartPos);
    i = Exogenon_Num_StartPos;

    while( Distance < (SHIP_RADIUS * 3.0F ) && i >= 0 )
    {
        Enemy->Object.Pos = Exogenon_StartPos[startpos];
        startpos++;
        if( startpos >= Exogenon_Num_StartPos )
            startpos = 0;
        Distance = DistanceVector2Vector( &Enemy->Object.Pos,&Ships[WhoIAm].Object.Pos );
        i--;
    }

    
    SetCurAnimSeq( EXOGENONSEQ_Move_Down, &Enemy->Object );
    Enemy->Object.AI_Mode = AIMODE_EXOGENON_MOVEDOWN;
}
Пример #4
0
/*===================================================================
	Procedure	:	AIR Formation Flying
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_LITTLEGEEK_FORMATION( register ENEMY * Enemy )
{
	OBJECT * SObject;
	VECTOR		Offset;
	VECTOR		TargetPos;
	ENEMY * LinkEnemy;
	SObject = &Enemy->Object;
	// Is it time to think???
	AI_THINK( Enemy , false ,false);

	LinkEnemy = Enemy->FormationLink;

	if( !LinkEnemy || ( LinkEnemy->Object.Shield <= (EnemyTypes[LinkEnemy->Type].Shield * 0.5F ) )  )
	{
		Enemy->Object.ControlType = ENEMY_CONTROLTYPE_FLY_AI;
		EnemyTypes[ENEMY_Boss_LittleGeek].Radius = 800 * GLOBAL_SCALE;
		EnemyTypes[ENEMY_Boss_BigGeek].Radius = 900.0F * GLOBAL_SCALE;
		AI_SetDOGFIGHT( Enemy );
		SetCurAnimSeq( LITTLEGEEKSEQ_Open, &Enemy->Object );
		Enemy->FormationLink = NULL;
		return;
	}

	SetCurAnimSeq( LITTLEGEEKSEQ_Stop, &Enemy->Object );

	Offset = Enemy->FormationOffset;
	ApplyMatrix( &LinkEnemy->Object.Mat, &Offset, &TargetPos );
	TargetPos.x += LinkEnemy->Object.Pos.x;
	TargetPos.y += LinkEnemy->Object.Pos.y;
	TargetPos.z += LinkEnemy->Object.Pos.z;

	Enemy->Object.Pos = TargetPos;

	Enemy->Object.Quat = LinkEnemy->Object.Quat;
	Enemy->Object.Mat = LinkEnemy->Object.Mat;
	Enemy->Object.InvMat = LinkEnemy->Object.InvMat;
	Enemy->Object.FinalMat = LinkEnemy->Object.FinalMat;
	Enemy->Object.FinalInvMat = LinkEnemy->Object.FinalInvMat;
	EnemyTypes[ENEMY_Boss_LittleGeek].Radius = 0.0F;

}
Пример #5
0
/*===================================================================
	Procedure	:	AIR Formation Flying
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_AIR_FORMATION( register ENEMY * Enemy )
{
	float	Dist;
	OBJECT * TObject;
	OBJECT * SObject;
	VECTOR		NewPos;
	VECTOR		TempVector;
	VECTOR		TempUpVector;
	VECTOR		TempOffset = { 0.0F, 0.0F, 0.0F };
	VECTOR		Offset;
	VECTOR		TargetPos;
	VECTOR		TempDir;
	ENEMY * LinkEnemy;

	SObject = &Enemy->Object;
	// Is it time to think???
	AI_THINK( Enemy , false ,false);

	LinkEnemy = Enemy->FormationLink;

	if( !LinkEnemy || ( LinkEnemy->Object.AI_Mode == AIMODE_RETREAT ) )
	{
		if( Enemy->AIFlags & ( AI_ICANSEEPLAYER + AI_ICANHEARPLAYER ) )
		{
			AI_SetDOGFIGHT( Enemy );
			return;
		}else{
			AI_SetFOLLOWPATH( Enemy );
			return;
		}
	}

	TObject = (OBJECT*) Enemy->TShip;

	
	Enemy->Timer -= framelag;
	if( Enemy->Timer < 0.0F )
		Enemy->Timer = 0.0F;

	Enemy->PrimaryFireTimer -= framelag;
	if( Enemy->PrimaryFireTimer < 0.0F )
		Enemy->PrimaryFireTimer = 0.0F;
	Enemy->SecondaryFireTimer -= framelag;
	if( Enemy->SecondaryFireTimer < 0.0F )
		Enemy->SecondaryFireTimer = 0.0F;

	if( Enemy->AIFlags & ( AI_ICANSEEPLAYER + AI_ICANHEARPLAYER ) )
	{
		Enemy->TNode = NULL;
		if( !(Enemy->Object.Flags & SHIP_Scattered ) && (Enemy->AIFlags & AI_ICANSEEPLAYER) && !(Enemy->AIFlags & AI_FRIENDLYFIRE) )
		{
			ApplyMatrix( &SObject->Mat, &Forward, &TempVector );
			ApplyMatrix( &SObject->Mat, &SlideUp, &TempUpVector );

			if( (Enemy->PrimaryFireTimer == 0.0F) && ( EnemyTypes[Enemy->Type].PrimaryWeaponType != NO_PRIMARY )  )
			{
				Enemy->PrimaryFireTimer = EnemyTypes[Enemy->Type].PrimaryFireRate + (float) Random_Range( (u_int16_t) EnemyTypes[Enemy->Type].PrimaryFireRate );
				EnemyFirePrimary( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, EnemyTypes[Enemy->Type].PrimaryWeaponType,
					Enemy->Object.Group, &Enemy->Object.Pos, &TempOffset, &TempVector, &TempUpVector,
					EnemyTypes[Enemy->Type].PowerLevel, 0.0F, false, NULL );
			}
		}
	}

	if( (Enemy->Object.Flags & SHIP_Scattered ) || ( (EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_RETREAT) && ( Enemy->Object.Shield <= (EnemyTypes[Enemy->Type].Shield * 0.15 ) ) ) )
	{
		// we should get out of hear..
		Enemy->FormationLink = NULL;
		AI_SetRETREAT( Enemy );
		return;
	}
	
	AI_UPDATEGUNS( Enemy );
	// Aim at target

	if( TObject && ( Enemy->AIFlags & AI_ICANSEEPLAYER ) )
	{
		if( EnemyTypes[Enemy->Type].PrimaryWeaponType != NO_PRIMARY )
		{
			AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move , &Enemy->Object.Pos , TObject , &NewPos ,   PrimaryWeaponAttribs[EnemyTypes[Enemy->Type].PrimaryWeaponType].Speed[0] );
		}else{
			NewPos = TObject->Pos;
		}
		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &NewPos );
		
		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}
			
		}
		
		Enemy->AI_Angle = AimData.Angle;
	}else{
		ApplyMatrix( &LinkEnemy->Object.Mat, &Forward, &TempDir );
		TempDir.x *= 1024.0F * GLOBAL_SCALE * 5.0F;
		TempDir.y *= 1024.0F * GLOBAL_SCALE * 5.0F;
		TempDir.z *= 1024.0F * GLOBAL_SCALE * 5.0F;
		NewPos.x = LinkEnemy->Object.Pos.x + TempDir.x;
		NewPos.y = LinkEnemy->Object.Pos.y + TempDir.y;
		NewPos.z = LinkEnemy->Object.Pos.z + TempDir.z;

		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &NewPos );
		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}
			
		}
		
		Enemy->AI_Angle = AimData.Angle;
	}

	if( Enemy->AvoidTimer )
	{
		Enemy->AIMoveFlags = Enemy->AvoidType;
	}else{

		Offset = Enemy->FormationOffset;
		ApplyMatrix( &LinkEnemy->Object.Mat, &Offset, &TargetPos );
		TargetPos.x += LinkEnemy->Object.Pos.x;
		TargetPos.y += LinkEnemy->Object.Pos.y;
		TargetPos.z += LinkEnemy->Object.Pos.z;

		Dist = DistanceVector2Vector( &TargetPos , &Enemy->Object.Pos);

		if( Dist > (EnemyTypes[Enemy->Type].Radius * 0.75F) )
		{
			Offset.x = TargetPos.x - Enemy->Object.Pos.x;
			Offset.y = TargetPos.y - Enemy->Object.Pos.y;
			Offset.z = TargetPos.z - Enemy->Object.Pos.z;

			ApplyMatrix( &Enemy->Object.InvMat, &Offset, &TargetPos );

			if( TargetPos.x < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_LEFT;
			}
			if( TargetPos.x > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_RIGHT;
			}
			if( TargetPos.y < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_DOWN;
			}
			if( TargetPos.y > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_UP;
			}
			if( TargetPos.z < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_BACK;
			}
			if( TargetPos.z > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
			}

		}
	}
}
Пример #6
0
/*===================================================================
	Procedure	:	AI Spline Movement....
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_SPLINE_FOLLOWPATH( register ENEMY * Enemy )
{
	NODE * TNode;
	NODE * Node1;
	NODE * Node2;
	NODE * Node3;
	NODE * Node4;
	VECTOR	OldPos;
	VECTOR	MoveOffset;
	float	Distance;
	float	WantedDistance;
	float	Time;
	float	Tstep;
	VECTOR	TempPos;
	int Count;

	OldPos = Enemy->Object.Pos;

	if( !Enemy->SplineNode1 )
	{
		//We have to start
		TNode = Enemy->Object.NearestNode;

		Enemy->SplineNode1 = (void*) TNode;
		Enemy->SplineNode2 = (void*) TNode;
		Node1 = (NODE*)Enemy->SplineNode1;
		Node2 = (NODE*)Enemy->SplineNode2;
		Enemy->SplineNode3 = (void*) FindSuitableSplineNode( Enemy->Object.NodeNetwork ,Node2 , Node1 , Node2 , NULL , NULL );
		Node3 = (NODE*)Enemy->SplineNode3;
		Enemy->SplineNode4 = (void*) FindSuitableSplineNode( Enemy->Object.NodeNetwork ,Node3 , Node1 , Node2 , Node3 , NULL );

	}
	Node1 = (NODE*)Enemy->SplineNode1;
	Node2 = (NODE*)Enemy->SplineNode2;
	Node3 = (NODE*)Enemy->SplineNode3;
	Node4 = (NODE*)Enemy->SplineNode4;


	WantedDistance = (EnemyTypes[Enemy->Type].MaxMoveRate*0.65F) * framelag;

	Tstep = ( WantedDistance / DistanceVector2Vector( &Node2->Pos , &Node3->Pos ) ) * 0.1F;

	Distance = DistanceVector2Vector( &Node2->Pos , &Node3->Pos );
	Time = (Distance / (EnemyTypes[Enemy->Type].MaxMoveRate * 0.65F) );
	
	Distance = 0.0F;
	Count = 0;
	do
	{
		Enemy->Timer += Tstep;

		if( Enemy->Timer >= 1.0F )
		{
			Enemy->SplineNode1 = Enemy->SplineNode2;
			Enemy->SplineNode2 = Enemy->SplineNode3;
			Enemy->SplineNode3 = Enemy->SplineNode4;
			Node1 = (NODE*)Enemy->SplineNode1;
			Node2 = (NODE*)Enemy->SplineNode2;
			Node3 = (NODE*)Enemy->SplineNode3;
			
			Enemy->Timer = ((Enemy->Timer - 1.0F) * Time);
			Distance = DistanceVector2Vector( &Node2->Pos , &Node3->Pos );
			Time = (Distance / (EnemyTypes[Enemy->Type].MaxMoveRate*0.65F) );
			Enemy->Timer /= Time;
			
			Enemy->SplineNode4 = (void*) FindSuitableSplineNodeRandom( Enemy->Object.NodeNetwork ,Node3 , Node1 , Node2 , Node3 , NULL );
			Node4 = (NODE*)Enemy->SplineNode4;
			Tstep = ( WantedDistance / DistanceVector2Vector( &Node2->Pos , &Node3->Pos ) ) * 0.1F;

			if( Node3 && (Node3->Flags&NODE_TERMINATE) )
			{
				KillUsedEnemy( Enemy );
				return;
			}
		}
	
		
		TempPos = Enemy->Object.Pos;

		spline(&Enemy->Object.Pos, Enemy->Timer, &Node1->Pos, &Node2->Pos, &Node3->Pos, &Node4->Pos);

		Distance += DistanceVector2Vector( &Enemy->Object.Pos , &TempPos);
		Count++;

	}while( ( Distance < WantedDistance ) && (Count < 100) );
	

	AI_THINK( Enemy , true , true);

	if( (Enemy->AIFlags & AI_ANYPLAYERINRANGE) )
	{
		Enemy->PrimaryFireTimer -= framelag;
		if( Enemy->PrimaryFireTimer < 0.0F )
			Enemy->PrimaryFireTimer = 0.0F;
		
		if(Enemy->PrimaryFireTimer == 0.0F)
		{
			if( !Enemy->TShip )
			{
				AI_DO_SCAN( Enemy );
			}
			Enemy->PrimaryFireTimer  =	RESET_VALIDATE_TIME + (float) Random_Range( (u_int16_t) RESET_VALIDATE_TIME );
		}
	}
	AI_UPDATEGUNS( Enemy );

	MoveOffset.x = Enemy->Object.Pos.x - OldPos.x;
	MoveOffset.y = Enemy->Object.Pos.y - OldPos.y;
	MoveOffset.z = Enemy->Object.Pos.z - OldPos.z;

	Enemy->Object.Group = MoveGroup( &Mloadheader, &OldPos, Enemy->Object.Group, &MoveOffset );


}
Пример #7
0
/*===================================================================
	Procedure	:	AIR Retreat And run away
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_AIR_RETREAT( register ENEMY * Enemy )
{
	OBJECT * TObject;
	OBJECT * SObject;
	NODE * TNode;
	NODE * NewNode;

	SObject = &Enemy->Object;
	// Is it time to think???
	AI_THINK( Enemy , false , false);

	TObject = (OBJECT*) Enemy->TShip;

	if( !TObject )
	{
		AI_SetFOLLOWPATH( Enemy );
		return;
	}
	
	Enemy->Timer -= framelag;

	if( Enemy->Timer < 0.0F )
		Enemy->Timer = 0.0F;
	
	if( !Enemy->TNode )
	{
		Enemy->TNode = Enemy->Object.NearestNode;
		Enemy->Timer = EnemyTypes[Enemy->Type].Behave.RetreatTime;	// How long I Run away for...
	}
	
	AI_UPDATEGUNS( Enemy );
	// Aim at target

	if( Enemy->TNode )
	{
		if ( Enemy->Timer == 0.0F )
		{
			// I Only have a certian amount of time to Run Away..
			AI_SetFOLLOWPATH( Enemy );
			return;
		}

		TNode = (NODE*) Enemy->TNode;

		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &TNode->Pos );

		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
			if( ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_DONTSTOPANDTURN ) || ( (AimData.Angle.x < 15.0F) && (AimData.Angle.x > -15.0F) &&	(AimData.Angle.y < 15.0F) && (AimData.Angle.y > -15.0F) ) )
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			if( ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_DONTSTOPANDTURN ) || ( (AimData.Angle.x < 15.0F) && (AimData.Angle.x > -15.0F) &&	(AimData.Angle.y < 15.0F) && (AimData.Angle.y > -15.0F) && (AimData.Angle.y < 3.0F) && (AimData.Angle.y > -3.0F)) )
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}

		}
		
		if( DistanceVector2Vector( &Enemy->Object.Pos , &TNode->Pos ) < 64.0F )
		{
			Enemy->Object.NearestNode = TNode;


			if( !(Enemy->Object.NodeNetwork&TNode->NetMask) && Enemy->Object.LastNearestNode && !(EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_LEAVENETWORK) )
			{
				// The node Im Targetting is not on my network...Better try and find one...
				TNode = WhichNode( 1 , Enemy->Object.NearestNode , Enemy->Object.LastNearestNode );
				
				if( !TNode )
				{
					Enemy->Object.LastNearestNode = NULL;
					return;
				}
				
				if( !AI_ClearLOSNonZero( &Enemy->Object, &TNode->Pos , EnemyTypes[Enemy->Type].Radius  ) )
				{
					// cant see the ideal node so just keep going to my previous target...
				}else{
				Enemy->TNode = TNode;
				}
			}else{
				// If I can leave my network to follow a target then do so if I have to...
				if( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_LEAVENETWORK )
					NewNode = (void*) WhichRetreatNode( 1 , Enemy->Object.NearestNode , TObject->NearestNode );
				else
					NewNode = (void*) WhichRetreatNode( Enemy->Object.NodeNetwork , Enemy->Object.NearestNode , TObject->NearestNode );

				if( !NewNode || !AI_ClearLOSNonZero( &Enemy->Object, &NewNode->Pos , EnemyTypes[Enemy->Type].Radius  ) ) 
				{
					// cant see the ideal node so just keep going to my previous target...
				}else{
					Enemy->TNode = NewNode;
				}
			}
		}
	}else{
		Enemy->TNode = Enemy->Object.NearestNode;

	}
	Enemy->AI_Angle = AimData.Angle;
}
Пример #8
0
/*===================================================================
	Procedure	:	AIR Follow Path
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_AIR_FOLLOWPATH( register ENEMY * Enemy )
{
	OBJECT * SObject;
	NODE * TNode;
	VECTOR	TempVector = { 0.0F , 0.0F , 0.0F };
	VECTOR	TempUpVector;
	VECTOR	TempForwardVector;
	u_int16_t	MineIndex;

	SObject = &Enemy->Object;

	AI_THINK( Enemy , false , false );

	if( !(Enemy->AIFlags & AI_ANYPLAYERINRANGE) )
		return;

	if( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ATTACK_ONSITE )
	{
		Tinfo->Flags = 0;
		SET_TARGET_PLAYERS;
		AI_GetDistToNearestTarget( Enemy );
		Enemy->TShip = Tinfo->TObject;
	}

	if( Enemy->TShip && ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ATTACK_ONSITE ) )
	{
		if( Enemy->AIFlags&AI_ICANSEEPLAYER )
		{
			AI_SetDOGFIGHT( Enemy );
			return;
		}else if( Enemy->AIFlags&AI_ICANHEARPLAYER )
		{
			AI_SetMOVETOTARGET( Enemy );
			return;
		}
	}


	if( (Enemy->AIFlags&AI_MINEAVOID) && (EnemyTypes[Enemy->Type].Behave.Flags&AI_BEHAVIOUR_ATTACKMINES) )
	{
		Enemy->AvoidTimer = 0.0F;
		Enemy->AvoidType = 0;
		AI_SetKILLMINE( Enemy );
		return;
	}
	
	
	if( TNode = (NODE*) Enemy->TNode )
	{
		if( !(Enemy->Object.NodeNetwork&TNode->NetMask) )
		{
			// The node Im Targetting is not on my network...Better try and find one...
			if( Enemy->Object.LastNearestNode )
			{
				TNode = (NODE*) ( Enemy->TNode = WhichNode( 1 , Enemy->Object.NearestNode , Enemy->Object.LastNearestNode ) );
				
				if( !TNode )
				{
					AI_SetSCAN( Enemy );
					return;
				}
				
				if( !AI_ClearLOSNonZero( &Enemy->Object, &TNode->Pos , EnemyTypes[Enemy->Type].Radius  ) )
				{
					// couldnt find a node that will take me to my target so go back to my nearest...
					TNode = (NODE*) ( Enemy->TNode = Enemy->Object.NearestNode );
				}
			}
		}

		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &TNode->Pos );
		Enemy->AI_Angle = AimData.Angle;

		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
			if( ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_DONTSTOPANDTURN ) || ( (AimData.Angle.x < 15.0F) && (AimData.Angle.x > -15.0F) &&	(AimData.Angle.y < 15.0F) && (AimData.Angle.y > -15.0F) ) )
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			if( ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_DONTSTOPANDTURN ) || ( (AimData.Angle.x < 15.0F) && (AimData.Angle.x > -15.0F) &&	(AimData.Angle.y < 15.0F) && (AimData.Angle.y > -15.0F) && (AimData.Angle.y < 3.0F) && (AimData.Angle.y > -3.0F)) )
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}

		}

		
		if( DistanceVector2Vector( &Enemy->Object.Pos , &TNode->Pos ) < 64.0F )
		{
			Tinfo->Flags = 0;
			SET_TARGET_NODES;
			AI_GetDistToNearestTarget( Enemy );
			Enemy->TNode = Tinfo->TObject;
		}
		// MINES........
		if(	(Enemy->AIFlags&AI_MINEAVOID) && (EnemyTypes[Enemy->Type].Behave.Flags&AI_BEHAVIOUR_AVOIDMINES) )
		{
			// A Mine is close....And I can See it...
			TNode = ChooseAlternateNode( Enemy->Object.NodeNetwork , Enemy->Object.NearestNode , Enemy->TNode );
			Enemy->TNode = TNode;
			Enemy->AIFlags &= ~AI_MINEAVOID;
			Enemy->AIMoveFlags &= ~AI_CONTROL_FORWARD;
		}

		if( !Enemy->AvoidTimer)
		{
			TNode = Enemy->Object.NearestNode;
			if( (TNode->Flags&NODE_DROPMINES) && (EnemyTypes[Enemy->Type].Behave.Flags&AI_BEHAVIOUR_DROPMINES) ) 
			{
				Enemy->SecondaryFireTimer -= framelag;
				if( Enemy->SecondaryFireTimer < 0.0F )
					Enemy->SecondaryFireTimer = 0.0F;
				
				if( (Enemy->SecondaryFireTimer == 0.0F) )
				{
					Enemy->SecondaryFireTimer = EnemyTypes[Enemy->Type].SecondaryFireRate + (float) Random_Range( (u_int16_t) EnemyTypes[Enemy->Type].SecondaryFireRate );
					//This is where we Lay Mines....
					
					ApplyMatrix( &Enemy->Object.Mat, &Forward, &TempForwardVector );
					ApplyMatrix( &Enemy->Object.Mat, &SlideUp, &TempUpVector );
					
					MineIndex = InitOneSecBull( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, Enemy->Object.Group,
								&Enemy->Object.Pos, &TempVector, &TempForwardVector, &TempUpVector,
								&TempVector, EnemyTypes[Enemy->Type].SecondaryWeaponType, false );

					if( MineIndex != (u_int16_t) -1 )
					{
						SecBulls[MineIndex].LifeSpan = 10.0F * 60.0F;
					}
				}
			}
		}
	}else{
		// If no target node has been found yet go to the nearest one...
		Enemy->TNode = Enemy->Object.NearestNode;
	}
}
Пример #9
0
/*===================================================================
	Procedure	:	CRAWL Follow Path
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_CRAWL_FOLLOWPATH( register ENEMY * Enemy )
{
	OBJECT * SObject;
	NODE * TNode;

	SObject = &Enemy->Object;

	AI_THINK( Enemy , false , false);

	if( !(Enemy->AIFlags & AI_ANYPLAYERINRANGE) )
		return;

	Enemy->Timer -= framelag;

	if( Enemy->Timer < 0.0F )
		Enemy->Timer = 0.0F;
	
	if(Enemy->Timer == 0.0F)
	{
		if( !(Enemy->AIFlags & AI_ICANSEEPLAYER ))
		{
			if( !Enemy->TShip )
			{
				AI_DO_SCAN( Enemy );
			}
		}
		Enemy->Timer  =	RESET_VALIDATE_TIME + (float) Random_Range( (u_int16_t) RESET_VALIDATE_TIME );
	}
	
	AI_UPDATEGUNS( Enemy );


	if( (Enemy->Type == ENEMY_Legz) || (Enemy->Type == ENEMY_LEADER_Legz) )
	{
		if( !Enemy->Object.Animating )
		{
			SetCurAnimSeq( 0, &Enemy->Object );
		}
		Enemy->Object.AnimSpeed = 0.5F + ( ( Enemy->Object.Speed.z / EnemyTypes[Enemy->Type].MaxMoveRate ) * 2.0F );
	}

	
	if( TNode = (NODE*) Enemy->TNode )
	{

		if( !(EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_NOTURN) )
		{
			AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &TNode->SolidPos );
			Enemy->AIMoveFlags |= AimData.Flags;
			Enemy->AI_Angle = AimData.Angle;

 
			if( ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_DONTSTOPANDTURN ) || ( (AimData.Angle.y < 10.0F) && (AimData.Angle.y > -10.0F) ) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
			}
		}else{
			Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
		}

		if(Enemy->PickNewNodeNow)
		{
			Enemy->PickNewNodeNow = false;

			Enemy->LastTNode = TNode;


			if( !Enemy->NextTNode )
			{
				Enemy->Object.NearestNode = TNode;
				Enemy->NextTNode = FindSuitableSplineNode( Enemy->Object.NodeNetwork, Enemy->Object.NearestNode , Enemy->Object.NearestNode , Enemy->LastTNode , Enemy->NextTNode , Enemy->TNode );
			}
			
			TNode = Enemy->NextTNode;
			Enemy->TNode = TNode;


			if( TNode )
			{
				Enemy->Object.NearestNode = TNode;
				Enemy->NextTNode = FindSuitableSplineNode( Enemy->Object.NodeNetwork, Enemy->Object.NearestNode , Enemy->Object.NearestNode , Enemy->LastTNode , Enemy->NextTNode , Enemy->TNode );
			}
			return;
		}
	}else{
		// If no target node has been found yet go to the nearest one...
		Enemy->TNode = Enemy->Object.NearestNode;
		Enemy->NextTNode = NULL;
	}


}