void CNodeNonterminal::Predict ( CDataset *pData, unsigned long iRow, double &dFadj ) { signed char schWhichNode = WhichNode(pData,iRow); if(schWhichNode == -1) { pLeftNode->Predict(pData, iRow, dFadj); } else if(schWhichNode == 1) { pRightNode->Predict(pData, iRow, dFadj); } else { pMissingNode->Predict(pData, iRow, dFadj); } }
/*------------------------------------------------------------------- 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 ); }
void CNodeNonterminal::Predict ( double *adX, unsigned long cRow, unsigned long cCol, unsigned long iRow, double &dFadj ) { signed char schWhichNode = WhichNode(adX,cRow,cCol,iRow); if(schWhichNode == -1) { pLeftNode->Predict(adX,cRow,cCol,iRow,dFadj); } else if(schWhichNode == 1) { pRightNode->Predict(adX,cRow,cCol,iRow,dFadj); } else { pMissingNode->Predict(adX,cRow,cCol,iRow,dFadj); } }
/*=================================================================== 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; }
/*=================================================================== 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; } }