XIIIMP
Class SabotageBotController

source: C:\XIII\XIIIMP\Classes\SabotageBotController.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Controller
         |
         +--Engine.AIController
            |
            +--XIIIMP.BotController
               |
               +--XIIIMP.SabotageBotController
Direct Known Subclasses:None

class SabotageBotController
extends XIIIMP.BotController

//----------------------------------------------------------- // //-----------------------------------------------------------
Variables
 , AttackPhaseNumber
           0:Attack, 1:Defense
 DefendPoint, AttackPoint
           0:Attack, 1:Defense
 Array AttackPointList
           0:Attack, 1:Defense
 TimeToWaitBeforeStart, AttackPointTime
           0:Attack, 1:Defense
 int BombSpotStatus[3]
           0:Taken, 1:Free
 Array DefendSpotList_1,DefendSpotList_2,DefendSpotList_3
           0:Taken, 1:Free
 bool FireMvt
           0:Attack, 1:Defense
 bool ForceContinueAttackPhase
           0:Attack, 1:Defense
 bool ForceUpFire
           0:Attack, 1:Defense
 EnemyTeam, FriendTeam
 Array GroupPointList
           0:Attack, 1:Defense
 , IHaveTheBomb
           0:Attack, 1:Defense
 DefendTime, MaxDefendTime
           0:Attack, 1:Defense
 Array MySubTeam
 Array MyTeam
 Array OtherSubTeam
 SubTeamID, OtherSubTeamID
           0 or 1
 , ReadyForNextAttackPoint
           0:Attack, 1:Defense
 Array SnipeSpotList_1,SnipeSpotList_2,SnipeSpotList_3
           0:Taken, 1:Free
 XIIIMPSabotageStorage StorageObj
           0:Attack, 1:Defense
 SubTeamBotSwitchTheSpot, SubTeamInit
           0:Attack, 1:Defense
 int TeamStatus
           0:Attack, 1:Defense
 TotalDefendTime, TotalMaxDefendTime
           0:Attack, 1:Defense
 3 ]
           0:Attack, 1:Defense
 bool forceSwitchSpot
           0:Attack, 1:Defense

States
CoverTheBomb, PutTheBomb, TakeTheBomb, GoToAttackSpot, Seek, CoverFight, Kill, Dead, AntiBug, WaitStart, BackToHomeBase, DefendTheSpot, GoToDefenseSpot

Function Summary
 bool BombCarrier(Pawn Other)
     
//__________________________________________________________________
 void BombIsActivated(MPBombingBase Target)
     
//__________________________________________________________________
 void CallTheOtherBotOfMySubTeamInReinforcement()
     
//__________________________________________________________________
 void CallTheOtherSubTeamInReinforcement()
     
//__________________________________________________________________
 void ChooseAttackSpot()
     
//__________________________________________________________________
 void ChooseDefendSpot()
     
//__________________________________________________________________
 bool CoverFightOrKill(Pawn Other)
     
//__________________________________________________________________
 void FindTeamRole()
     
//__________________________________________________________________
 void FocusFire(Pawn Other)
     
//__________________________________________________________________
 void GetAttackPointTime()
     
//__________________________________________________________________
 void GetGroupPathNode(int Start, int End)
     
//__________________________________________________________________
 int GetLifePriority()
     
//__________________________________________________________________
 bool GetNumberOfEnemyInTheGrenadArea(BotGrenadTarget Target)
     
//__________________________________________________________________
 int GiveTheNumberOfEnemyInTheZone(Pawn Other)
     
//__________________________________________________________________
 void GrenadPossibility(GrenadPathNode GrenadNode)
     
//__________________________________________________________________
 void InitPickUpList()
     
//__________________________________________________________________
 void InitializeSubTeam()
     
//__________________________________________________________________
 bool IsEnemy(Pawn Target)
     
//__________________________________________________________________
 bool IsInBombArea(Pawn Other)
     
//__________________________________________________________________
 void ObjectifIsDestroyed(MPBombingBase Target)
     
//__________________________________________________________________
 void SayToOhterSubTeamBotThanTheSpotChange()
     
//__________________________________________________________________
 bool ShouldTakeTheBomb(Pawn Other)
     
//__________________________________________________________________
 void SwitchDefendSpot()
     
//__________________________________________________________________
 void UpDateOrder(int OldOrder, int NewOrder)
     
//__________________________________________________________________


State CoverTheBomb Function Summary
 void FindAttackSpot()
     
//--------------------------------------------------------------


State PutTheBomb Function Summary
 void Kassos()
     
//--------------------------------------------------------------
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------


State TakeTheBomb Function Summary
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------


State GoToAttackSpot Function Summary
 void AloneOrNot()
     
//--------------------------------------------------------------
 bool AllReady()
     
//--------------------------------------------------------------
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------
 void FindAttackSpot()
     
//--------------------------------------------------------------


State Seek Function Summary


State CoverFight Function Summary
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------


State Kill Function Summary


State Dead Function Summary


State AntiBug Function Summary


State WaitStart Function Summary
 void AloneOrNot()
     
//--------------------------------------------------------------
 bool AllReady()
     
//--------------------------------------------------------------
 void FindAttackSpot()
     
//--------------------------------------------------------------


State BackToHomeBase Function Summary
 bool AllReady()
     
//--------------------------------------------------------------
 void FindAttackSpot()
     
//--------------------------------------------------------------


State DefendTheSpot Function Summary
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------


State GoToDefenseSpot Function Summary
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------
 void FindDefendSpot()
     
//--------------------------------------------------------------



Source Code


00001	//-----------------------------------------------------------
00002	//
00003	//-----------------------------------------------------------
00004	class SabotageBotController extends BotController;
00005	
00006	var Array<Controller> EnemyTeam, FriendTeam;
00007	var Array<SabotageBotController> MyTeam;
00008	var Array<SabotageBotController> MySubTeam;
00009	var Array<SabotageBotController> OtherSubTeam;
00010	var int BombSpotStatus[3]; // 0:Taken, 1:Free
00011	var Array<NavigationPoint> DefendSpotList_1,DefendSpotList_2,DefendSpotList_3;
00012	var Array<NavigationPoint> SnipeSpotList_1,SnipeSpotList_2,SnipeSpotList_3;
00013	var int SubTeamID, OtherSubTeamID; // 0 or 1
00014	var int TeamStatus; // 0:Attack, 1:Defense
00015	var bool ForceUpFire;
00016	var NavigationPoint DefendPoint, AttackPoint;
00017	var bool forceSwitchSpot;
00018	var float TotalDefendTime, TotalMaxDefendTime;
00019	var float DefendTime, MaxDefendTime;
00020	var bool FireMvt;
00021	var bool SubTeamBotSwitchTheSpot, SubTeamInit;
00022	var XIIIMPSabotageStorage StorageObj;
00023	var bool WaitToStart , ReadyForNextAttackPoint;
00024	var float TimeToWaitBeforeStart, AttackPointTime;
00025	var MPBombingBase BombPoint[ 3 ];
00026	var int AttackPathGroup, AttackPhaseIndex , AttackPhaseNumber;
00027	var Array<NavigationPoint> AttackPointList;
00028	var Array<NavigationPoint> GroupPointList;
00029	var bool AloneRun , IHaveTheBomb;
00030	var bool ForceContinueAttackPhase;
00031	
00032	const Order_GoToDefenseSpot    =   1048576;
00033	const Order_DefendTheSpot      =   2097152;
00034	const Order_WaitToStart        =   4194304;
00035	const Order_CoverFight         =  33554432; //25
00036	const Order_GoToAttackSpot     =  67108864; //26
00037	const Order_CoverTheBomb       = 134217728; //27
00038	const Order_TakeTheBomb        = 268435456; //28
00039	const Order_PutTheBomb         = 536870912; //29
00040	const Order_BackToHomeBase     = 524288;
00041	
00042	const cAttackStatus  = 0;
00043	const cDefenseStatus = 1;
00044	
00045	//__________________________________________________________________
00046	
00047	function bool GetNumberOfEnemyInTheGrenadArea(BotGrenadTarget Target)
00048	{
00049	    local Controller C;
00050	    local int NbFriend,NbEnemy;
00051	
00052	    if( Rand( 100 ) < 50 )
00053	    {
00054	        foreach DynamicActors(class'Controller', C)
00055	        {
00056	            if( C != self )
00057	            {
00058	                if( VSize( Target.Location - C.Pawn.Location ) < 600 )
00059	                {
00060	                    if( IsEnemy( C.Pawn ) )
00061	                        NbEnemy++;
00062	                    else
00063	                        NbFriend++;
00064	                }
00065	            }
00066	        }
00067	
00068	        if( ( NbEnemy != 0 ) && ( NbFriend == 0 ) )
00069	            return true;
00070	        else
00071	            return false;
00072	    }
00073	    else
00074	        return false;
00075	}
00076	
00077	//__________________________________________________________________
00078	
00079	function GrenadPossibility( GrenadPathNode GrenadNode )
00080	{
00081	    if( GrenadNode.Team != TeamID )
00082	        return;
00083	
00084	    super.GrenadPossibility( GrenadNode );
00085	}
00086	
00087	//__________________________________________________________________
00088	
00089	function bool BombCarrier( Pawn Other )
00090	{
00091	    local weapon TheBomb;
00092	
00093	    TheBomb = Weapon(Other.FindInventoryType(class'MPBomb'));
00094	
00095	    if( ( TheBomb == none ) || (  TheBomb.AmmoType.AmmoAmount == 0 ) )
00096	        return false;
00097	    else
00098	        return true;
00099	}
00100	
00101	//__________________________________________________________________
00102	
00103	function bool ShouldTakeTheBomb( Pawn Other )
00104	{
00105	    local int Loop;
00106	    local float DistToTheBomb;
00107	
00108	    if( ! SubTeamInit )
00109	        InitializeSubTeam();
00110	
00111	    if( ! StorageObj.TheBombPick.ReadyToPickUp(3) )
00112	        return false;
00113	
00114	    DistToTheBomb = VSize( Other.Location - StorageObj.TheBombPick.Location );
00115	
00116	    for( Loop=0;Loop<MyTeam.Length;Loop++ )
00117	    {
00118	        if( MyTeam[ Loop ].FindOrder(Order_TakeTheBomb ) )
00119	            return false;
00120	
00121	        if( VSize( MyTeam[ Loop ].Pawn.Location - StorageObj.TheBombPick.Location ) < DistToTheBomb )
00122	            return false;
00123	    }
00124	
00125	    return true;
00126	}
00127	
00128	//__________________________________________________________________
00129	
00130	function GetAttackPointTime()
00131	{
00132	    AttackPointTime = StorageObj.Temporisation[ AttackPhaseIndex ];
00133	}
00134	
00135	//__________________________________________________________________
00136	
00137	function GetGroupPathNode( int Start , int End )
00138	{
00139	    local int Loop, NbPossibility;
00140	
00141	    End++;
00142	
00143	    //log("!!! GetGroupPathNode"@Start@End@"!!!");
00144	
00145	    for( Loop=0;Loop<GroupPointList.Length;Loop++ )
00146	    {
00147	      //   log(" >"@GroupPointList[ Loop ]@GroupPathNode(GroupPointList[ Loop ]).StartPointID@GroupPathNode(GroupPointList[ Loop ]).EndPointID);
00148	
00149	         if( ( GroupPathNode(GroupPointList[ Loop ]).StartPointID == Start ) && ( GroupPathNode(GroupPointList[ Loop ]).EndPointID == End ) )
00150	         {
00151	             StorageObj.MyGPN = GroupPathNode(GroupPointList[ Loop ]);
00152	             break;
00153	         }
00154	    }
00155	
00156	    //log(" > Choose :"@StorageObj.MyGPN);
00157	
00158	    NbPossibility = 1;
00159	
00160	    if( StorageObj.MyGPN.Possibility2.Length != 0 )
00161	        NbPossibility++;
00162	
00163	    if( StorageObj.MyGPN.Possibility3.Length != 0 )
00164	        NbPossibility++;
00165	
00166	    StorageObj.PossibilityChoice = Rand( NbPossibility );
00167	
00168	    StorageObj.Possibility.Length = 0;
00169	
00170	    //log(" > Possibility :"@StorageObj.PossibilityChoice);
00171	
00172	
00173	    switch( StorageObj.PossibilityChoice )
00174	    {
00175	        case 0 :
00176	                for( Loop=0;Loop<StorageObj.MyGPN.Possibility1.Length;Loop++ )
00177	                {
00178	                    StorageObj.Possibility.Length = StorageObj.Possibility.Length+1;
00179	                    StorageObj.Possibility[ StorageObj.Possibility.Length-1 ] = StorageObj.MyGPN.Possibility1[ Loop ];
00180	
00181	                    StorageObj.Temporisation.Length = StorageObj.Temporisation.Length+1;
00182	                    StorageObj.Temporisation[ StorageObj.Temporisation.Length-1 ] = StorageObj.MyGPN.Temporisation1[ Loop ];
00183	                }
00184	
00185	                break;
00186	        case 1 :
00187	                for( Loop=0;Loop<StorageObj.MyGPN.Possibility2.Length;Loop++ )
00188	                {
00189	                    StorageObj.Possibility.Length = StorageObj.Possibility.Length+1;
00190	                    StorageObj.Possibility[ StorageObj.Possibility.Length-1 ] = StorageObj.MyGPN.Possibility2[ Loop ];
00191	
00192	                    StorageObj.Temporisation.Length = StorageObj.Temporisation.Length+1;
00193	                    StorageObj.Temporisation[ StorageObj.Temporisation.Length-1 ] = StorageObj.MyGPN.Temporisation2[ Loop ];
00194	                }
00195	
00196	                break;
00197	        case 2 :
00198	                for( Loop=0;Loop<StorageObj.MyGPN.Possibility3.Length;Loop++ )
00199	                {
00200	                    StorageObj.Possibility.Length = StorageObj.Possibility.Length+1;
00201	                    StorageObj.Possibility[ StorageObj.Possibility.Length-1 ] = StorageObj.MyGPN.Possibility3[ Loop ];
00202	
00203	                    StorageObj.Temporisation.Length = StorageObj.Temporisation.Length+1;
00204	                    StorageObj.Temporisation[ StorageObj.Temporisation.Length-1 ] = StorageObj.MyGPN.Temporisation3[ Loop ];
00205	                }
00206	
00207	                break;
00208	    }
00209	}
00210	
00211	//__________________________________________________________________
00212	
00213	function bool IsInBombArea( Pawn Other )
00214	{
00215	    local int Loop;
00216	    local float DistToBombBase;
00217	
00218	    for( Loop=0;Loop<3;Loop++)
00219	    {
00220	        if( BombSpotStatus[ Loop ] == 1 )
00221	        {
00222	            if( VSize( Other.Location - BombPoint[ Loop ].Location ) < 2500 )
00223	                return true;
00224	        }
00225	    }
00226	
00227	    return  false;
00228	}
00229	
00230	//__________________________________________________________________
00231	
00232	function BombIsActivated(MPBombingBase Target)
00233	{
00234	    local int Loop, TargetID;
00235	
00236	    TargetID = -1;
00237	
00238	    for( Loop=0;Loop<3;Loop++ )
00239	    {
00240	       if( BombPoint[ Loop ] == Target )
00241	       {
00242	           TargetID = Loop;
00243	           break;
00244	       }
00245	    }
00246	
00247	    if( TargetID == -1 )
00248	        return;
00249	
00250	    if( TargetID == StorageObj.CurrentDefendSpot[ SubTeamID ] )
00251	        return;
00252	
00253	    StorageObj.CurrentDefendSpot[ SubTeamID ] = TargetID;
00254	    TeamRole = TargetID;
00255	
00256	    LastDefaultOrderTime = 0;
00257	    SubTeamBotSwitchTheSpot = true;
00258	}
00259	
00260	//__________________________________________________________________
00261	
00262	function ObjectifIsDestroyed(MPBombingBase Target)
00263	{
00264	    local int Loop, TargetID;
00265	
00266	    TargetID = -1;
00267	
00268	    for( Loop=0;Loop<3;Loop++ )
00269	    {
00270	       if( BombPoint[ Loop ] == Target )
00271	       {
00272	           TargetID = Loop;
00273	           break;
00274	       }
00275	    }
00276	
00277	    if( TargetID == -1 )
00278	        return;
00279	
00280	    BombSpotStatus[ TargetID ] = 0;
00281	    StorageObj.CurrentAttackSpot[ 0 ] = -1;
00282	    StorageObj.CurrentDefendSpot[ 0 ] = -1;
00283	    StorageObj.CurrentDefendSpot[ 1 ] = -1;
00284	
00285	    if( TeamStatus == cAttackStatus )
00286	    {
00287	        if( ! FindOrder( Order_BackToHomeBase ) )
00288	            AddOrder(79,Order_BackToHomeBase,"BackToHomeBase",Order_CoverTheBomb);
00289	    }
00290	    else
00291	    {
00292	        SubTeamBotSwitchTheSpot = true;
00293	
00294	    }
00295	}
00296	
00297	//__________________________________________________________________
00298	
00299	function InitializeSubTeam()
00300	{
00301	    local SabotageBotController Bot;
00302	
00303	    SubTeamInit = true;
00304	
00305	    foreach DynamicActors(class'SabotageBotController', BOT)
00306	    {
00307	        if( ( Bot.TeamID == TeamID ) && ( BOT != self ) )
00308	        {
00309	            if( Bot.SubTeamID == SubTeamID )
00310	            {
00311	                MySubTeam.Length = MySubTeam.Length+1;
00312	                MySubTeam[ MySubTeam.Length-1 ] = BOT;
00313	            }
00314	            else
00315	            {
00316	                OtherSubTeam.Length = OtherSubTeam.Length+1;
00317	                OtherSubTeam[ OtherSubTeam.Length-1 ] = BOT;
00318	            }
00319	        }
00320	    }
00321	}
00322	
00323	//__________________________________________________________________
00324	
00325	function int GiveTheNumberOfEnemyInTheZone( Pawn Other )
00326	{
00327	    local int NbEnemy,Loop;
00328	
00329	    NbEnemy=1;
00330	
00331	    for( Loop=0;Loop<EnemyTeam.Length;Loop++ )
00332	    {
00333	         if( ( EnemyTeam[ Loop ] != Other ) && ( VSize( Other.Location - EnemyTeam[ Loop ].Location ) < 1000 ) )
00334	             NbEnemy++;
00335	    }
00336	
00337	    return NbEnemy+10;
00338	}
00339	
00340	//__________________________________________________________________
00341	
00342	event Timer()
00343	{
00344	    if( MyWeaponIsAGrenad )
00345	    {
00346	        bFire=1;
00347	        Pawn.Weapon.Fire(0);
00348	        bFire=0;
00349	
00350	        SetTimer2(0.5,false);
00351	        SetTimer(0.0,false);
00352	    }
00353	    else if( XIIIWeapon(Pawn.Weapon).WeaponMode == WM_SemiAuto )
00354	    {
00355	        bFire=1;
00356	        Pawn.Weapon.Fire(0);
00357	        bFire=0;
00358	
00359	        SetTimer2( XIIIWeapon(Pawn.Weapon).ShotTime + ( 3 - Skill )*0.25,false );
00360	        SetTimer(0.0,false);
00361	    }
00362	    else if ( ( ( XIIIPawn(Pawn).WeaponMode == 'FM_M16' ) && ( XIIIWeapon(Pawn.Weapon).HasAltAmmo() ) ) && ( VSize( Enemy.Location - Pawn.Location ) < 1600 ) )
00363	    {
00364	        bFire=1;
00365	        Pawn.Weapon.AltFire(0);
00366	        bFire=0;
00367	
00368	        SetTimer2( 0.5,false );
00369	        SetTimer(0.0,false);
00370	    }
00371	    else
00372	    {
00373	        bFire=1;
00374	        Pawn.Weapon.Fire(0);
00375	
00376	        SetTimer2( 2.5 - skill/2,false );
00377	        SetTimer(0.0,false);
00378	    }
00379	}
00380	
00381	//__________________________________________________________________
00382	
00383	event Timer2()
00384	{
00385	    if( MyWeaponIsAGrenad )
00386	    {
00387	        Pawn.Weapon.AIRating = 0.11;
00388	        SwitchWeapon();
00389	        SetTimer(1.0,false);
00390	        SetTimer2(0.0,false);
00391	    }
00392	    else if( XIIIWeapon(Pawn.Weapon).WeaponMode == WM_SemiAuto )
00393	    {
00394	        if( XIIIPawn(Pawn).WeaponMode == 'FM_Snipe' )
00395	            SetTimer(0.01 + FRand()/2,false);
00396	        else
00397	            SetTimer(0.01,false);
00398	
00399	        SetTimer2(0.0,false);
00400	    }
00401	    else if ( ( ( XIIIPawn(Pawn).WeaponMode == 'FM_M16' ) && ( XIIIWeapon(Pawn.Weapon).HasAltAmmo() ) ) && ( VSize( Enemy.Location - Pawn.Location ) < 1600 ) )
00402	    {
00403	        SetTimer(0.1,false);
00404	        SetTimer2(0.0,false);
00405	    }
00406	    else
00407	    {
00408	        bFire=0;
00409	        SetTimer(0.01,false);
00410	        SetTimer2(0.0,false);
00411	    }
00412	
00413	    if( ! Pawn.Weapon.HasAmmo() )
00414	        SwitchWeapon();
00415	}
00416	
00417	//__________________________________________________________________
00418	
00419	function FocusFire(Pawn Other)
00420	{
00421	    if( IsInState('CoverFight') )
00422	        return;
00423	
00424	    if( IsInState('Kill') )
00425	        return;
00426	
00427	    if( IsShootable( Other ) )
00428	    {
00429	        //log("   > SeePlayer");
00430	        SeePlayer( Other );
00431	    }
00432	    else
00433	    {
00434	        //log("   > Order_Seek");
00435	        Enemy = Other;
00436	        AddOrder( 70 ,Order_Seek,"Seek", 0);
00437	    }
00438	}
00439	
00440	//__________________________________________________________________
00441	
00442	function CallTheOtherBotOfMySubTeamInReinforcement()
00443	{
00444	    local int Loop;
00445	
00446	    if( ! SubTeamInit )
00447	        InitializeSubTeam();
00448	   if( DBugBot )
00449		{
00450	    	log("");
00451	    	log("CallTheOtherBotOfMySubTeamInReinforcement");
00452		}
00453	
00454	    if( MySubTeam.Length != 0 )
00455	    {
00456	        for( Loop=0;Loop<MySubTeam.Length;Loop++ )
00457	        {
00458	            //log(" >"@MySubTeam[ Loop ]);
00459	            MySubTeam[ Loop ].FocusFire( Enemy );
00460	        }
00461	    }
00462	}
00463	
00464	//__________________________________________________________________
00465	
00466	function CallTheOtherSubTeamInReinforcement()
00467	{
00468	    local int Loop;
00469	
00470	    if( ! SubTeamInit )
00471	        InitializeSubTeam();
00472	
00473	    if( OtherSubTeam.Length != 0 )
00474	    {
00475	        StorageObj.CurrentDefendSpot[ OtherSubTeamID ] = StorageObj.CurrentDefendSpot[ SubTeamID ];
00476	
00477	        for( Loop=0;Loop<OtherSubTeam.Length;Loop++ )
00478	        {
00479	             OtherSubTeam[ Loop ].LastDefaultOrderTime = 0;
00480	             OtherSubTeam[ Loop ].TeamRole = TeamRole;
00481	             OtherSubTeam[ Loop ].SubTeamBotSwitchTheSpot = true;
00482	        }
00483	    }
00484	}
00485	
00486	//__________________________________________________________________
00487	
00488	function SayToOhterSubTeamBotThanTheSpotChange()
00489	{
00490	    local int Loop;
00491	
00492	    if( ! SubTeamInit )
00493	        InitializeSubTeam();
00494	
00495	    if( MySubTeam.Length != 0 )
00496	    {
00497	        for( Loop=0;Loop<MySubTeam.Length;Loop++ )
00498	        {
00499	             MySubTeam[ Loop ].LastDefaultOrderTime = 0;
00500	             MySubTeam[ Loop ].TeamRole = TeamRole;
00501	             MySubTeam[ Loop ].SubTeamBotSwitchTheSpot = true;
00502	        }
00503	    }
00504	}
00505	
00506	//__________________________________________________________________
00507	
00508	function UpDateOrder(int OldOrder,int NewOrder)
00509	{
00510	    if( NewOrder == TeamRole )
00511	        return;
00512	
00513	    if( DBugBot )
00514	    {
00515	        Log("");
00516	        Log("[ BOT"@ID@"] : UpDateOrder Spot"@TeamRole@"->"@NewOrder);
00517	    }
00518	    if( StorageObj.CurrentAttackSpot[ SubTeamID ] == -1 )  //FRD initialisation des listes de points
00519	          ChooseAttackSpot();
00520	    TeamRole = NewOrder;
00521	
00522	    if( TeamStatus == cDefenseStatus )
00523	    {
00524	        StorageObj.CurrentDefendSpot[ SubTeamID ] = TeamRole;
00525	        StorageObj.ForceDefenseTeamRole = true;
00526	    }
00527	    else
00528	    {
00529	        StorageObj.CurrentAttackSpot[ SubTeamID ] = TeamRole;
00530	        StorageObj.ForceAttackTeamRole = true;
00531	    }
00532	
00533	    ForceSwitchSpot = true;
00534	
00535	    LastDefaultOrderTime = 0;
00536	}
00537	
00538	//__________________________________________________________________
00539	
00540	function bool CoverFightOrKill( Pawn Other )
00541	{
00542	    if( FastTrace( Other.Location, Pawn.Location ) )
00543	        return false;
00544	    else
00545	        return true;
00546	}
00547	
00548	//__________________________________________________________________
00549	
00550	function ChooseDefendSpot()
00551	{
00552	    local int NbFreeSpot, Loop;
00553	    local int TmpSpot[ 3 ];
00554	
00555	    for( Loop = 0 ; Loop < 3 ; Loop++ )
00556	    {
00557	        if( BombSpotStatus[ Loop ] == 1 )
00558	        {
00559	            TmpSpot[ NbFreeSpot ] = Loop;
00560	            NbFreeSpot++;
00561	        }
00562	    }
00563	
00564	    TeamRole = TmpSpot[Rand( NbFreeSpot )];
00565	    StorageObj.CurrentDefendSpot[ SubTeamID ] = TeamRole;
00566	
00567	    if( ! SubTeamInit )
00568	        InitializeSubTeam();
00569	
00570	    if( MySubTeam.Length != 0 )
00571	    {
00572	        for( Loop=0;Loop<MySubTeam.Length;Loop++ )
00573	        {
00574	             MySubTeam[ Loop ].TeamRole = TeamRole;
00575	        }
00576	    }
00577	
00578	    if( DBugBot )
00579	    {
00580	        Log("");
00581	        Log("[ BOT"@ID@"] : Choose Defend Spot for Team"@SubTeamID@" --> Spot N"$StorageObj.CurrentDefendSpot[ SubTeamID ]);
00582	    }
00583	}
00584	
00585	//__________________________________________________________________
00586	
00587	function ChooseAttackSpot()
00588	{
00589	    local int NbFreeSpot, Loop , OldTeamRole;
00590	    local int TmpSpot[ 3 ];
00591	
00592	    for( Loop = 0 ; Loop < 3 ; Loop++ )
00593	    {
00594	        if( BombSpotStatus[ Loop ] == 1 )
00595	        {
00596	            TmpSpot[ NbFreeSpot ] = Loop;
00597	            NbFreeSpot++;
00598	        }
00599	    }
00600	
00601	    OldTeamRole = TeamRole;
00602	
00603	    TeamRole = TmpSpot[Rand( NbFreeSpot )];
00604	
00605	    StorageObj.CurrentAttackSpot[ SubTeamID ] = TeamRole;
00606	
00607	    GetGroupPathNode( 0 , TeamRole );
00608	
00609	    if( ! SubTeamInit )
00610	        InitializeSubTeam();
00611	
00612	    if( MySubTeam.Length != 0 )
00613	    {
00614	        for( Loop=0;Loop<MySubTeam.Length;Loop++ )
00615	        {
00616	             MySubTeam[ Loop ].TeamRole = TeamRole;
00617	        }
00618	    }
00619	
00620	    if( DBugBot )
00621	    {
00622	        Log("");
00623	        Log("[ BOT"@ID@"] : Choose Attack Spot for Team"@SubTeamID@" --> Spot N"$StorageObj.CurrentAttackSpot[ SubTeamID ]);
00624	    }
00625	
00626	    for( Loop=0;Loop<FriendTeam.Length;Loop++ )
00627	    {
00628	        XIIIBombHud(PlayerController(FriendTeam[Loop]).MyHud).BotBlink[ 0 ]=0;
00629	        XIIIBombHud(PlayerController(FriendTeam[Loop]).MyHud).BotBlink[ 1 ]=0;
00630	        XIIIBombHud(PlayerController(FriendTeam[Loop]).MyHud).BotBlink[ 2 ]=0;
00631	        XIIIBombHud(PlayerController(FriendTeam[Loop]).MyHud).BotBlink[ TeamRole ]=1;
00632	    }
00633	}
00634	
00635	//__________________________________________________________________
00636	
00637	function SwitchDefendSpot()
00638	{
00639	    local int NbFreeSpot, Loop;
00640	    local int TmpSpot[ 3 ];
00641	
00642	    for( Loop = 0 ; Loop < 3 ; Loop++ )
00643	    {
00644	        if( ( BombSpotStatus[ Loop ] == 1 ) && ( Loop != StorageObj.CurrentDefendSpot[ SubTeamID ] ) )
00645	        {
00646	            TmpSpot[ NbFreeSpot ] = Loop;
00647	            NbFreeSpot++;
00648	        }
00649	    }
00650	
00651	    if( NbFreeSpot != 0 )
00652	    {
00653	        TeamRole = TmpSpot[Rand( NbFreeSpot )];
00654	        StorageObj.CurrentDefendSpot[ SubTeamID ] = TeamRole;
00655	
00656	        SayToOhterSubTeamBotThanTheSpotChange();
00657	
00658	        if( DBugBot )
00659	        {
00660	            Log("");
00661	            Log("[ BOT"@ID@"] : switch Defend Spot for Team"@SubTeamID@" --> Spot N"$StorageObj.CurrentDefendSpot[ SubTeamID ]);
00662	        }
00663	    }
00664	}
00665	
00666	//__________________________________________________________________
00667	
00668	event AddDefaultOrders()
00669	{
00670	    if( Pawn == none )
00671	    {
00672	        gotostate('AntiBug');
00673	        return;
00674	    }
00675	
00676	    if( ( Level.TimeSeconds - LastDefaultOrderTime < 3.0 ) && ( LastDefaultOrderTime != 0) )
00677	    {
00678			 if( ( DBugBot ) || ( DBugWarning ) )
00679				Log("[ WARNING ][ ORDER ][ BOT"@ID@"] : Runaway Loop !...");
00680	
00681	        AddOrder(79,Order_UnBlock,"UnBlock",0);
00682	    }
00683	    else
00684	    {
00685	        if( WaitToStart )
00686	            AddOrder(101,Order_WaitToStart,"WaitToStart",0);
00687	
00688	        if( TeamStatus == cDefenseStatus )
00689	        {
00690	            AddOrder(60,Order_GoToDefenseSpot,"GoToDefenseSpot",0);
00691	        }
00692	        else if( TeamStatus == cAttackStatus )
00693	        {
00694	            AddOrder(60,Order_GoToAttackSpot,"GoToAttackSpot",0);
00695	        }
00696	    }
00697	
00698	    LastDefaultOrderTime = Level.TimeSeconds;
00699	}
00700	
00701	//__________________________________________________________________
00702	
00703	
00704	event ChangeState()
00705	{
00706	    if( Pawn == none )
00707	        return;
00708	
00709	    switch( CurrentOrder.TypeId )
00710	    {
00711	        case Order_GoToDefenseSpot : gotoState( 'GoToDefenseSpot' ); break;
00712	        case Order_DefendTheSpot : gotoState( 'DefendTheSpot' ); break;
00713	        case Order_WaitToStart : gotoState( 'WaitStart' ); break;
00714	        case Order_CoverFight : gotoState( 'CoverFight' ); break;
00715	        case Order_GoToAttackSpot : gotoState( 'GoToAttackSpot' ); break;
00716	        case Order_CoverTheBomb : gotoState( 'CoverTheBomb' ); break;
00717	        case Order_TakeTheBomb : gotoState( 'TakeTheBomb' ); break;
00718	        case Order_PutTheBomb : gotoState( 'PutTheBomb' ); break;
00719	        case Order_BackToHomeBase : gotoState( 'BackToHomeBase' ); break;
00720	        case Order_GrenadLauncher : gotoState( 'GrenadLauncher' ); break;
00721	        case Order_Kill : GotoState( 'Kill' ); break;
00722	        case Order_Life : GotoState( 'Life' ); break;
00723	        case Order_Seek : GotoState( 'Seek' ); break;
00724	        case Order_Fear : gotoState( 'Fear' ); break;
00725	        case Order_Weapon : GotoState( 'Weapon' ); break;
00726	        case Order_Armor : GotoState( 'Armor' ); break;
00727	        case Order_SnipeSpot : GotoState( 'SnipeSpot' ); break;
00728	        case Order_SnipeAndKill : GotoState( 'SnipeAndKill' ); break;
00729	        case Order_UnBlock : gotoState( 'UnBlock' ); break;
00730	        case Order_TrakNar : gotoState( 'TrakNar' ); break;
00731	    }
00732	}
00733	
00734	//__________________________________________________________________
00735	
00736	function InitPickUpList()
00737	{
00738	    local PickUp A;
00739	    local NavigationPoint Nav;
00740	    local Pawn P;
00741	    local SabotageBotController Bot;
00742	    local int Loop;
00743		local Controller C;
00744	//    local XIIIMPBotInteraction BI;
00745	
00746	
00747	    bInitPickUpList = true;
00748	
00749		//--------------
00750	
00751	//    for ( C=Level.ControllerList; C!=None; C= C.NextController )
00752	//	{
00753	//        if( XIIIMPPlayerController(C) != none )
00754	//        {
00755	//            if( C.PlayerReplicationInfo.Team.TeamIndex == TeamID )
00756	//            {
00757	//                BI = XIIIMPBotInteraction(XIIIMPPlayerController(C).MyInteraction );
00758	//                BI.BotControllerList.Length = BI.BotControllerList.Length+1;
00759	//                BI.BotControllerList[ BI.BotControllerList.Length-1 ] = self;
00760	//
00761	//                if( TeamID == 0 )
00762	//                    BI.GameType = 2;
00763	//                else
00764	//                    BI.GameType = 1;
00765	//            }
00766	//        }
00767	//	}
00768	
00769		//--------------
00770	
00771	    Nav = Level.NavigationPointList;
00772	
00773	    while( Nav != none)
00774	    {
00775	        if( DefensePathNode( Nav) != none )
00776	        {
00777	            if( DefensePathNode( Nav).BotLevel <= Skill )
00778	            {
00779	                switch( DefensePathNode( Nav).DefensePointID )
00780	                {
00781	                    case 1 :
00782	                        if( DefensePathNode( Nav).SnipeSpot )
00783	                        {
00784	                            SnipeSpotList_1.Length = SnipeSpotList_1.Length+1;
00785	                            SnipeSpotList_1[ SnipeSpotList_1.Length-1 ] = Nav;
00786	                        }
00787	                        else
00788	                        {
00789	                            DefendSpotList_1.Length = DefendSpotList_1.Length+1;
00790	                            DefendSpotList_1[ DefendSpotList_1.Length-1 ] = Nav;
00791	                        }
00792	                        break;
00793	                    case 2 :
00794	                        if( DefensePathNode( Nav).SnipeSpot )
00795	                        {
00796	                            SnipeSpotList_2.Length = SnipeSpotList_2.Length+1;
00797	                            SnipeSpotList_2[ SnipeSpotList_2.Length-1 ] = Nav;
00798	                        }
00799	                        else
00800	                        {
00801	                            DefendSpotList_2.Length = DefendSpotList_2.Length+1;
00802	                            DefendSpotList_2[ DefendSpotList_2.Length-1 ] = Nav;
00803	                        }
00804	                        break;
00805	                    case 3 :
00806	                        if( DefensePathNode( Nav).SnipeSpot )
00807	                        {
00808	                            SnipeSpotList_3.Length = SnipeSpotList_3.Length+1;
00809	                            SnipeSpotList_3[ SnipeSpotList_3.Length-1 ] = Nav;
00810	                        }
00811	                        else
00812	                        {
00813	                            DefendSpotList_3.Length = DefendSpotList_3.Length+1;
00814	                            DefendSpotList_3[ DefendSpotList_3.Length-1 ] = Nav;
00815	                        }
00816	                        break;
00817	                }
00818	            }
00819	        }
00820	        else if( MPBombingBase( Nav) != none )
00821	        {
00822	            BombPoint[ MPBombingBase( Nav).BombPointID -1 ] = MPBombingBase( Nav);
00823	        }
00824	        else if( AttackPathNode( Nav) != none )
00825	        {
00826	            AttackPointList.Length = AttackPointList.Length+1;
00827	            AttackPointList[ AttackPointList.Length-1 ] = Nav;
00828	        }
00829	        else if( GroupPathNode( Nav) != none )
00830	        {
00831	            GroupPointList.Length = GroupPointList.Length+1;
00832	            GroupPointList[ GroupPointList.Length-1 ] = Nav;
00833	        }
00834	
00835	
00836	
00837	
00838	        Nav = Nav.NextNavigationPoint;
00839	    }
00840	
00841		//--------------
00842	
00843	    foreach DynamicActors(class'XIIIMPSabotageStorage', StorageObj)
00844	    {
00845	        if( StorageObj.TeamId == TeamId )
00846	            break;
00847	    }
00848	
00849		//--------------
00850	
00851	    foreach DynamicActors(class'PickUp', A)
00852	    {
00853	        FullPickUpList.Length = FullPickUpList.Length+1;
00854	        FullPickUpList[ FullPickUpList.Length-1 ] = A;
00855	
00856	        if( XIIIMPBombPick( A ) != none )
00857	            StorageObj.TheBombPick = XIIIMPBombPick( A );
00858	    }
00859	
00860		//--------------
00861	
00862	    foreach DynamicActors(class'SabotageBotController', BOT)
00863	    {
00864	        if( ( Bot.TeamID == TeamID ) && ( BOT != self ) )
00865	        {
00866	            MyTeam.Length = MyTeam.Length+1;
00867	            MyTeam[ MyTeam.Length-1 ] = BOT;
00868	        }
00869	    }
00870	
00871		//--------------
00872	
00873	    foreach DynamicActors(class'Controller', C)
00874	    {
00875	        if( IsEnemy(C.Pawn) )
00876	        {
00877	            EnemyTeam.Length = EnemyTeam.Length+1;
00878	            EnemyTeam[ EnemyTeam.Length-1 ] = C;
00879	        }
00880	        else
00881	        {
00882	            if( BotController(C) == none )
00883	            {
00884	                FriendTeam.Length = FriendTeam.Length+1;
00885	                FriendTeam[ FriendTeam.Length-1 ] = C;
00886	            }
00887	        }
00888	    }
00889	
00890		//--------------
00891	
00892	    TeamStatus = TeamId;
00893	    FindTeamRole();
00894	
00895	    if( TeamStatus == cAttackStatus )
00896	        RespawnTime=4.0;
00897	    else
00898	        RespawnTime=8.0;
00899	
00900	
00901		//--------------
00902	
00903	    if( DBugBot )
00904	    {
00905	        Log("");
00906	        Log("[ BOT"@ID@"][ Team"@TeamID@"][ Level"@int(Skill)@"] : PickUpList Construction");
00907	        log("    > DefendPoint 1="$DefendSpotList_1.Length@"+"@SnipeSpotList_1.Length);
00908	        log("    > DefendPoint 2="$DefendSpotList_2.Length@"+"@SnipeSpotList_2.Length);
00909	        log("    > DefendPoint 3="$DefendSpotList_3.Length@"+"@SnipeSpotList_3.Length);
00910	        Log("    > Other Team Bot :"@MyTeam.Length );
00911	
00912	        if( MyTeam.Length != 0 )
00913	        {
00914	            for( Loop = 0 ; Loop < MyTeam.Length ; Loop++ )
00915	                 log("     "@Loop@":"@MyTeam[ Loop ]);
00916	        }
00917	
00918	        Log("    > Enemy Team :"@EnemyTeam.Length );
00919	
00920	        if( EnemyTeam.Length != 0 )
00921	        {
00922	            for( Loop = 0 ; Loop < EnemyTeam.Length ; Loop++ )
00923	                 log("     "@Loop@":"@EnemyTeam[ Loop ]);
00924	        }
00925	
00926	        Log("    > SubTeam :"@SubTeamID);
00927	    }
00928	}
00929	
00930	//__________________________________________________________________
00931	
00932	function FindTeamRole()
00933	{
00934	    local int Loop,BestLevel,SecondBestLevel;
00935	    local SabotageBotController Best,SecondBest;
00936	    local Array<SabotageBotController> TmpTeam;
00937	    local SabotageBotController Bot;
00938	
00939	    if( TeamStatus == cAttackStatus )
00940	    {
00941	        SubTeamID = 0;
00942	        return;
00943	    }
00944	
00945	    foreach DynamicActors(class'SabotageBotController', BOT)
00946	    {
00947	        if( Bot.TeamID == TeamID )
00948	        {
00949	            TmpTeam.Length = TmpTeam.Length+1;
00950	            TmpTeam[ TmpTeam.Length-1 ] = BOT;
00951	        }
00952	    }
00953	
00954	    for( Loop=0;Loop<TmpTeam.Length;Loop++)
00955	    {
00956	        if( ( TmpTeam[Loop].Skill > BestLevel ) || ( Best == none ) )
00957	        {
00958	            BestLevel = TmpTeam[Loop].Skill;
00959	            Best = TmpTeam[Loop];
00960	        }
00961	    }
00962	
00963	    if( Best == self )
00964	    {
00965	        SubTeamID = 0;
00966	        OtherSubTeamID = 1;
00967	        return;
00968	    }
00969	
00970	    for( Loop=0;Loop<TmpTeam.Length;Loop++)
00971	    {
00972	        if( ( TmpTeam[Loop].Skill > SecondBestLevel ) || ( SecondBest == none ) )
00973	        {
00974	            if( TmpTeam[Loop] != Best )
00975	            {
00976	                SecondBestLevel = TmpTeam[Loop].Skill;
00977	                SecondBest = TmpTeam[Loop];
00978	            }
00979	        }
00980	    }
00981	
00982	    if( SecondBest == self )
00983	    {
00984	        SubTeamID = 0;
00985	        OtherSubTeamID = 1;
00986	        return;
00987	    }
00988	
00989	    SubTeamID = 1;
00990	    OtherSubTeamID = 0;
00991	}
00992	
00993	//__________________________________________________________________
00994	
00995	function int GetLifePriority()
00996	{
00997	    return 0;
00998	}
00999	
01000	//__________________________________________________________________
01001	
01002	function bool IsEnemy( Pawn Target )
01003	{
01004	    return ( Target.Controller.PlayerReplicationInfo.Team.TeamIndex != TeamID );
01005	}
01006	
01007	//__________________________________________________________________
01008	//__________________________________________________________________
01009	//                            GoToDefenseSpot
01010	//__________________________________________________________________
01011	//__________________________________________________________________
01012	
01013	state GoToDefenseSpot
01014	{
01015	    event BeginState()
01016	    {
01017	        if( DBugBot )
01018	        {
01019	            Log("");
01020	            Log("[ BOT"@ID@"] : *STATE* ---> Go To Defense Spot");
01021	        }
01022	
01023	        Enemy = none;
01024	        Pawn.ControllerPitch = 0;
01025	        Pawn.ShouldCrouch( false );
01026	
01027	        if( StorageObj.CurrentDefendSpot[ SubTeamID ] == -1 )
01028	            ChooseDefendSpot();
01029	         if( DBugBot )
01030				{
01031					log("");
01032					log("--------------------------------------------------");
01033					log(" > Defense Spot N"$StorageObj.CurrentDefendSpot[ SubTeamID ]+1);
01034					log("--------------------------------------------------");
01035					log("");
01036				}
01037	    }
01038	
01039	    //--------------------------------------------------------------
01040	
01041	    event EndState()
01042	    {
01043	        if( FireMvt )
01044	        {
01045	            Enemy = none;
01046	
01047	            bFire=0;
01048	            FireMvt=false;
01049	            SetTimer(0.0,false);
01050	            SetTimer2(0.0,false);
01051	
01052	            if (pawn!=none) Pawn.Weapon.ForceReload();
01053	        }
01054	
01055	        if (DefendPoint!=none) DefensePathNode(DefendPoint).Closed = false;
01056	    }
01057	
01058	    //--------------------------------------------------------------
01059	
01060	    function FindDefendSpot()
01061	    {
01062	        local Array<NavigationPoint> UseablePoint;
01063	        local int Loop;
01064	        local NavigationPoint TmpNode;
01065	
01066	        if ( Pawn.Weapon.InventoryGroup == 14 )
01067	        {
01068	            switch( StorageObj.CurrentDefendSpot[ SubTeamID ] )
01069	            {
01070	                case 0 :
01071	                    for( Loop=0; Loop<SnipeSpotList_1.Length ; Loop++ )
01072	                    {
01073	                        TmpNode = SnipeSpotList_1[Loop];
01074	
01075	                        if( ! DefensePathNode(TmpNode).Closed )
01076	                        {
01077	                            UseablePoint.Length = UseablePoint.Length+1;
01078	                            UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
01079	                        }
01080	                    }
01081	
01082	                    break;
01083	                case 1 :
01084	                    for( Loop=0; Loop<SnipeSpotList_2.Length ; Loop++ )
01085	                    {
01086	                        TmpNode = SnipeSpotList_2[Loop];
01087	
01088	                        if( ! DefensePathNode(TmpNode).Closed )
01089	                        {
01090	                            UseablePoint.Length = UseablePoint.Length+1;
01091	                            UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
01092	                        }
01093	                    }
01094	
01095	                    break;
01096	                case 2 :
01097	                    for( Loop=0; Loop<SnipeSpotList_3.Length ; Loop++ )
01098	                    {
01099	                        TmpNode = SnipeSpotList_3[Loop];
01100	
01101	                        if( ! DefensePathNode(TmpNode).Closed )
01102	                        {
01103	                            UseablePoint.Length = UseablePoint.Length+1;
01104	                            UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
01105	                        }
01106	                    }
01107	                 break;
01108	            }
01109	        }
01110	        else
01111	        {
01112	            switch( StorageObj.CurrentDefendSpot[ SubTeamID ] )
01113	            {
01114	                case 0 :
01115	                    for( Loop=0; Loop<DefendSpotList_1.Length ; Loop++ )
01116	                    {
01117	                        TmpNode = DefendSpotList_1[Loop];
01118	
01119	                        if( ! DefensePathNode(TmpNode).Closed )
01120	                        {
01121	                            UseablePoint.Length = UseablePoint.Length+1;
01122	                            UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
01123	                        }
01124	                    }
01125	
01126	                    break;
01127	                case 1 :
01128	                    for( Loop=0; Loop<DefendSpotList_2.Length ; Loop++ )
01129	                    {
01130	                        TmpNode = DefendSpotList_2[Loop];
01131	
01132	                        if( ! DefensePathNode(TmpNode).Closed )
01133	                        {
01134	                            UseablePoint.Length = UseablePoint.Length+1;
01135	                            UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
01136	                        }
01137	                    }
01138	
01139	                    break;
01140	                case 2 :
01141	                    for( Loop=0; Loop<DefendSpotList_3.Length ; Loop++ )
01142	                    {
01143	                        TmpNode = DefendSpotList_3[Loop];
01144	
01145	                        if( ! DefensePathNode(TmpNode).Closed )
01146	                        {
01147	                            UseablePoint.Length = UseablePoint.Length+1;
01148	                            UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
01149	                        }
01150	                    }
01151	
01152	                    break;
01153	            }
01154	        }
01155	
01156	        if( UseablePoint.Length != 0 )
01157				{
01158	            DefendPoint = UseablePoint[ Rand(UseablePoint.Length) ];
01159				}
01160	
01161	        else
01162				{
01163					log(self@" a plus de defend point de disponible");
01164	            DefendPoint = none;
01165				}
01166	    }
01167	
01168	    //--------------------------------------------------------------
01169	
01170	    function SomeoneWantKillMe( Pawn Agressor )
01171	    {
01172	        if( Agressor == Pawn )
01173	            return;
01174	
01175	        SeePlayer( Agressor );
01176	    }
01177	
01178	    //--------------------------------------------------------------
01179	
01180	    event SeePlayer( Pawn Seen )
01181	    {
01182	        local float DistToBombingPoint;
01183	        local int NbAttacker;
01184	
01185	        if( ( ( ! IsEnemy( Seen ) ) || DamnedImFlashed ) || ( ! IsShootable( Seen ) ) )
01186	            return;
01187	
01188	        if( Enemy == none )
01189	        {
01190	            DistToBombingPoint = VSize( Seen.Location - BombPoint[ StorageObj.CurrentDefendSpot[ SubTeamID ] ].Location );
01191	            NbAttacker = GiveTheNumberOfEnemyInTheZone( Seen );
01192	
01193	            Enemy = Seen;
01194	
01195	            if( ( ( StorageObj.CurrentDefendSpot[ OtherSubTeamID ] != StorageObj.CurrentDefendSpot[ SubTeamID ] ) && ( NbAttacker > 2 ) ) && ( DistToBombingPoint < 2000 ) )
01196	                CallTheOtherSubTeamInReinforcement();
01197	
01198	            if( ( NbAttacker > 2 ) && ( DistToBombingPoint < 2000 ) )
01199	                CallTheOtherBotOfMySubTeamInReinforcement();
01200	
01201	            if( FullPath && ( PathIndex > PathCacheSize -3 ) )
01202	            {
01203	                FireMvt=true;
01204	                SetTimer( (4-Skill)*0.2+FRand()/2 ,False );
01205	                Focus = Enemy;
01206	            }
01207	            else
01208	            {
01209	                if (DefendPoint!=none) DefensePathNode(DefendPoint).Closed = false;
01210	
01211	                if( !FindOrder( Order_Kill ) )
01212	                    AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01213	            }
01214	        }
01215	    }
01216	
01217	    //--------------------------------------------------------------
01218	
01219	    event EnemyNotVisible()
01220	    {
01221	        if( FireMvt )
01222	        {
01223	            Enemy = none;
01224	
01225	            bFire=0;
01226	            FireMvt=false;
01227	            SetTimer(0.0,false);
01228	            SetTimer2(0.0,false);
01229	
01230	            Pawn.Weapon.ForceReload();
01231	        }
01232	    }
01233	
01234	    //--------------------------------------------------------------
01235	
01236	Begin:
01237	
01238	    FindDefendSpot();
01239	
01240	    if( DefendPoint != none )
01241	    {
01242	        DefensePathNode(DefendPoint).Closed = true;
01243	
01244	        while( true )
01245	        {
01246	            NavPathStorage(DefendPoint);
01247	
01248	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01249	            {
01250	                MoveTarget = PathCache[ PathIndex ];
01251	                Focus=MoveTarget;
01252	
01253	                if( FireMvt )
01254	                    MoveToward( MoveTarget, Enemy , MoveSpeed );
01255	                else
01256	                    MoveToward( MoveTarget, Focus , MoveSpeed );
01257	
01258	                if( ForceSwitchSpot )
01259	                {
01260	                    if( DBugBot )
01261	                    {
01262	                        Log("");
01263	                        Log("[ BOT"@ID@"] : Player Change Order_GoToDefenseSpot");
01264	                    }
01265	
01266	                    ForceSwitchSpot = false;
01267	                    DefensePathNode(DefendPoint).Closed = false;
01268	                    goto('begin');
01269	                }
01270	
01271	                if( SubTeamBotSwitchTheSpot )
01272	                {
01273	                    if( DBugBot )
01274	                    {
01275	                        Log("");
01276	                        Log("[ BOT"@ID@"] : Other Bot Change Order_GoToDefenseSpot");
01277	                    }
01278	
01279	                    SubTeamBotSwitchTheSpot = false;
01280	                    DefensePathNode(DefendPoint).Closed = false;
01281	                    goto('begin');
01282	                }
01283	            }
01284	
01285	            if( FullPath )
01286	                break;
01287	        }
01288	    }
01289	    else
01290	    {
01291	        //log("Oups !");
01292	        RemoveOrder( Order_GoToDefenseSpot );
01293			  stop;
01294	    }
01295	
01296	    AddOrder(50,Order_DefendTheSpot,"DefendTheSpot",0);
01297	    RemoveOrder( Order_GoToDefenseSpot );
01298	}
01299	
01300	//__________________________________________________________________
01301	//__________________________________________________________________
01302	//                            DefendTheSpot
01303	//__________________________________________________________________
01304	//__________________________________________________________________
01305	
01306	state DefendTheSpot
01307	{
01308	    event BeginState()
01309	    {
01310	        if( DBugBot )
01311	        {
01312	            Log("");
01313	            Log("[ BOT"@ID@"] : *STATE* ---> DefendTheSpot");
01314	        }
01315	
01316	        Enemy = none;
01317	        //Pawn.ControllerPitch = 0;
01318	
01319	        Pawn.velocity=vect(0,0,0);
01320	        Pawn.acceleration=vect(0,0,0);
01321	        Focus = none;
01322	        FocalPoint = vector(DefendPoint.Rotation)+Pawn.Location;
01323	
01324	        if( DefensePathNode(DefendPoint).MustBeCrouched )
01325	        {
01326	            Pawn.ShouldCrouch( true );
01327	        }
01328	        else if( DefensePathNode(DefendPoint).DoNotCrouch )
01329	        {
01330	            Pawn.ShouldCrouch( false );
01331	        }
01332	        else if( Rand( 100 ) < 20 + Skill*20 )
01333	        {
01334	            Pawn.ShouldCrouch( true );
01335	        }
01336	        else
01337	            Pawn.ShouldCrouch( false );
01338	
01339	        Pawn.SpineYawControl(true,3000, 1.2);
01340	
01341	        if( TotalDefendTime == -1 )
01342	            TotalDefendTime = Level.TimeSeconds;
01343	        if( DBugBot )
01344	        		log(" > Defense Spot N"$StorageObj.CurrentDefendSpot[ SubTeamID ]);
01345	    }
01346	
01347	    //--------------------------------------------------------------
01348	
01349	    event EndState()
01350	    {
01351			  if (pawn!=none)
01352			  {
01353	        		Pawn.SpineYawControl(false,3000, 1.2);
01354	        		Pawn.ShouldCrouch( false );
01355			  }
01356	        DefensePathNode(DefendPoint).Closed = false;
01357	    }
01358	
01359	    //--------------------------------------------------------------
01360	
01361	    function SomeoneWantKillMe( Pawn Agressor )
01362	    {
01363	        if( Agressor == Pawn )
01364	            return;
01365	
01366	        SeePlayer( Agressor );
01367	    }
01368	
01369	    //--------------------------------------------------------------
01370	
01371	    event SeePlayer( Pawn Seen )
01372	    {
01373	        if( ( ( ! IsEnemy( Seen ) ) || DamnedImFlashed ) || ( ! IsShootable( Seen ) ) )
01374	            return;
01375	
01376	        if( Enemy == none )
01377	        {
01378	            TotalDefendTime = -1;
01379	            Enemy = Seen;
01380	
01381	            if( ( StorageObj.CurrentDefendSpot[ OtherSubTeamID ] != StorageObj.CurrentDefendSpot[ SubTeamID ] ) && ( GiveTheNumberOfEnemyInTheZone( Seen ) > 2 ) )
01382	                CallTheOtherSubTeamInReinforcement();
01383	
01384	            CallTheOtherBotOfMySubTeamInReinforcement();
01385	
01386	            if( CoverFightOrKill( Seen ) )
01387	            {
01388	                if( !FindOrder( Order_CoverFight ) )
01389	                    AddOrder(KillOrderPriority,Order_CoverFight,"Cover Fight",0);
01390	            }
01391	            else
01392	            {
01393	                if( !FindOrder( Order_Kill ) )
01394	                    AddOrder(KillOrderPriority,Order_Kill,"Kill",Order_DefendTheSpot);
01395	            }
01396	        }
01397	    }
01398	
01399	    //--------------------------------------------------------------
01400	
01401	Begin:
01402	
01403	    DefendTime = Level.TimeSeconds;
01404	    MaxDefendTime = 10 + Rand( 5 );
01405	
01406	    while( true )
01407	    {
01408	        Sleep( 1.0 );
01409	
01410	        if( ForceSwitchSpot )
01411	        {
01412	            if( DBugBot )
01413	            {
01414	                Log("");
01415	                Log("[ BOT"@ID@"] : Player Stop Order_DefendTheSpot");
01416	            }
01417	
01418	            TotalDefendTime = -1;
01419	            ForceSwitchSpot = false;
01420	            RemoveOrder( Order_DefendTheSpot );
01421	        }
01422	
01423	        if( SubTeamBotSwitchTheSpot )
01424	        {
01425	            if( DBugBot )
01426	            {
01427	                Log("");
01428	                Log("[ BOT"@ID@"] : Other Bot Stop Order_DefendTheSpot");
01429	            }
01430	
01431	            TotalDefendTime = -1;
01432	            SubTeamBotSwitchTheSpot = false;
01433	            RemoveOrder( Order_DefendTheSpot );
01434	        }
01435	
01436	        if( ( Level.TimeSeconds - DefendTime > MaxDefendTime ) || ( BombSpotStatus[ StorageObj.CurrentDefendSpot[ SubTeamID ] ] == 0 ) )
01437	            break;
01438	    }
01439	
01440	    if( ( ! StorageObj.ForceDefenseTeamRole ) && ( Level.TimeSeconds - TotalDefendTime > TotalMaxDefendTime ) )
01441	    {
01442	        TotalDefendTime = -1;
01443	        SwitchDefendSpot();
01444	    }
01445	
01446	    RemoveOrder( Order_DefendTheSpot );
01447	}
01448	
01449	
01450	//__________________________________________________________________
01451	//__________________________________________________________________
01452	//                            BackToHomeBase
01453	//__________________________________________________________________
01454	//__________________________________________________________________
01455	
01456	state BackToHomeBase
01457	{
01458	    event BeginState()
01459	    {
01460	        if( DBugBot )
01461	        {
01462	            Log("");
01463	            Log("[ BOT"@ID@"] : *STATE* ---> BackToHomeBase");
01464	        }
01465	
01466	        Pawn.ShouldCrouch( false );
01467	    }
01468	
01469	    //--------------------------------------------------------------
01470	
01471	    event EndState()
01472	    {
01473	        if (AttackPoint!=none) AttackPathNode(AttackPoint).Closed = false;
01474	    }
01475	
01476	    //--------------------------------------------------------------
01477	
01478	    function FindAttackSpot()
01479	    {
01480	        local Array<NavigationPoint> UseablePoint;
01481	        local int Loop, Tmp;
01482	        local NavigationPoint TmpNode;
01483	
01484	        for( Loop=0; Loop<AttackPointList.Length ; Loop++ )
01485	        {
01486	            TmpNode = AttackPointList[Loop];
01487	
01488	            if( AttackPathNode(TmpNode).Group == 0 )
01489	                Tmp++;
01490	
01491	            if( ( ! AttackPathNode(TmpNode).Closed ) && ( AttackPathNode(TmpNode).Group == 0 ) )
01492	            {
01493	                UseablePoint.Length = UseablePoint.Length+1;
01494	                UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
01495	            }
01496	        }
01497	
01498	    	if( DBugBot )
01499			{
01500	        		Log("");
01501	        		log("[ BOT"@ID@"] : BackToHomeBase ---> FreePoint:"@UseablePoint.Length$"/"$Tmp);
01502			}
01503	       if( UseablePoint.Length != 0 )
01504	            AttackPoint = UseablePoint[ Rand(UseablePoint.Length) ];
01505	        else
01506	            AttackPoint = none;
01507	    }
01508	
01509	    //--------------------------------------------------------------
01510	
01511	    function bool AllReady()
01512	    {
01513	        local int Loop , NbReady , NbBot;
01514	
01515	        for( Loop=0;Loop<MyTeam.Length;Loop++ )
01516	        {
01517	            if( MyTeam[ Loop ].IsInState('BackToHomeBase' ) )
01518	            {
01519	                NbBot++;
01520	
01521	                if( MyTeam[ Loop ].ReadyForNextAttackPoint )
01522	                    NbReady++;
01523	            }
01524	        }
01525	
01526	        if( NbReady == NbBot )
01527	            return true;
01528	        else
01529	            return false;
01530	    }
01531	
01532	    //--------------------------------------------------------------
01533	
01534	begin :
01535	
01536	    FindAttackSpot();
01537	
01538	    if( AttackPoint != none )
01539	    {
01540	        AttackPathNode(AttackPoint).Closed = true;
01541	
01542	        while( true )
01543	        {
01544	            NavPathStorage(AttackPoint);
01545	
01546	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01547	            {
01548	                MoveTarget = PathCache[ PathIndex ];
01549	                Focus=MoveTarget;
01550	
01551	                if( FireMvt )
01552	                    MoveToward( MoveTarget, Enemy , MoveSpeed );
01553	                else
01554	                    MoveToward( MoveTarget, Focus , MoveSpeed );
01555	            }
01556	
01557	            if( FullPath )
01558	                break;
01559	        }
01560	    }
01561		 else
01562		 {
01563	        RemoveOrder( Order_GoToDefenseSpot );
01564			  stop;
01565		 }
01566	
01567	    if( AllReady() )
01568	    {
01569	        if( StorageObj.TheBombPick.ReadyToPickUp(0) )
01570	        {
01571	            if( DBugBot )
01572	                Log("---> Oups ! The Bomb --> TakeMyBomb");
01573	
01574	            Sleep( 0.2 + FRand() );
01575	            AttackPathNode(AttackPoint).Closed = false;
01576	
01577	            Goto('TakeMyBomb');
01578	        }
01579	    }
01580	
01581	    ReadyForNextAttackPoint=true;
01582	
01583	    Pawn.ControllerPitch = 0;
01584	
01585	    Pawn.velocity=vect(0,0,0);
01586	    Pawn.acceleration=vect(0,0,0);
01587	    Focus = none;
01588	    FocalPoint = vector(AttackPoint.Rotation)+Pawn.Location;
01589	
01590	    if( AttackPathNode(AttackPoint).MustBeCrouched )
01591	    {
01592	        Pawn.ShouldCrouch( true );
01593	    }
01594	    else if( AttackPathNode(AttackPoint).DoNotCrouch )
01595	    {
01596	        Pawn.ShouldCrouch( false );
01597	    }
01598	    else if( Rand( 100 ) < 20 + Skill*20 )
01599	    {
01600	        Pawn.ShouldCrouch( true );
01601	    }
01602	    else
01603	        Pawn.ShouldCrouch( false );
01604	
01605	    Pawn.SpineYawControl(true,3000, 1.2);
01606	
01607	    while( true )
01608	    {
01609	        if( AllReady() )
01610	        {
01611	            Sleep( 1.0 + FRand() );
01612	
01613	            ReadyForNextAttackPoint=false;
01614	            Pawn.SpineYawControl(false,3000, 1.2);
01615	            Pawn.ShouldCrouch( false );
01616	            AttackPathNode(AttackPoint).Closed = false;
01617	
01618	            RemoveOrder( Order_BackToHomeBase );
01619	        }
01620	        else
01621	            Sleep( 0.5 );
01622	    }
01623	
01624	    //--------------------------------------------------------------
01625	
01626	TakeMyBomb:
01627	
01628	    Pawn.ShouldCrouch( false );
01629	
01630	    Item = StorageObj.TheBombPick;
01631	
01632	    while( true )
01633	    {
01634	        PickUpPathStorage(Item);
01635	
01636	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01637	        {
01638	            MoveTarget = PathCache[ PathIndex ];
01639	            Focus=MoveTarget;
01640	
01641	            MoveToward( MoveTarget, Focus , MoveSpeed );
01642	        }
01643	
01644	        if( FullPath )
01645	            break;
01646	    }
01647	
01648	    Goto('begin');
01649	}
01650	
01651	//__________________________________________________________________
01652	//__________________________________________________________________
01653	//                            WaitStart
01654	//__________________________________________________________________
01655	//__________________________________________________________________
01656	
01657	state WaitStart
01658	{
01659	    event BeginState()
01660	    {
01661	        if( DBugBot )
01662	        {
01663	            Log("");
01664	            Log("[ BOT"@ID@"] : *STATE* ---> WaitStart");
01665	        }
01666	
01667	        Pawn.ShouldCrouch( false );
01668	        ForceContinueAttackPhase = false;
01669	    }
01670	
01671	    //--------------------------------------------------------------
01672	
01673	    event EndState()
01674	    {
01675			  if (pawn!=none)
01676			  {
01677		        Pawn.SpineYawControl(false,3000, 1.2);
01678		        Pawn.ShouldCrouch( false );
01679			  }
01680	        if (attackpoint!=none) AttackPathNode(AttackPoint).Closed = false;
01681	    }
01682	
01683	    //--------------------------------------------------------------
01684	
01685	    function FindAttackSpot()
01686	    {
01687	        local Array<NavigationPoint> UseablePoint;
01688	        local int Loop, Tmp;
01689	        local NavigationPoint TmpNode;
01690	
01691	        for( Loop=0; Loop<AttackPointList.Length ; Loop++ )
01692	        {
01693	            TmpNode = AttackPointList[Loop];
01694	
01695	            if( AttackPathNode(TmpNode).Group == 0 )
01696	                Tmp++;
01697	
01698	            if( ( ! AttackPathNode(TmpNode).Closed ) && ( AttackPathNode(TmpNode).Group == 0 ) )
01699	            {
01700	                UseablePoint.Length = UseablePoint.Length+1;
01701	                UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
01702	            }
01703	        }
01704	
01705	      if( DBugBot )
01706			{
01707				Log("");
01708	        	Log("[ BOT"@ID@"] : BackToHomeBase ---> FreePoint:"@UseablePoint.Length$"/"$Tmp);
01709			}
01710	
01711	        if( UseablePoint.Length != 0 )
01712	            AttackPoint = UseablePoint[ Rand(UseablePoint.Length) ];
01713	        else
01714	            AttackPoint = none;
01715	    }
01716	
01717	    //--------------------------------------------------------------
01718	
01719	    function bool AllReady()
01720	    {
01721	        local int Loop , NbReady , NbBot;
01722	
01723	        for( Loop=0;Loop<MyTeam.Length;Loop++ )
01724	        {
01725	            if( MyTeam[ Loop ].IsInState('WaitStart' ) )
01726	            {
01727	                NbBot++;
01728	
01729	                if( MyTeam[ Loop ].ReadyForNextAttackPoint )
01730	                    NbReady++;
01731	            }
01732	        }
01733	
01734	        if( NbReady == NbBot )
01735	            return true;
01736	        else
01737	            return false;
01738	    }
01739	
01740	    //--------------------------------------------------------------
01741	
01742	    function AloneOrNot()
01743	    {
01744	        local int Loop , NbReady , NbBot;
01745	
01746	        for( Loop=0;Loop<MyTeam.Length;Loop++ )
01747	        {
01748	            if( MyTeam[ Loop ].IsInState('WaitStart' ) )
01749	                NbBot++;
01750	        }
01751	
01752	        if( NbBot == 0 )
01753	            AloneRun = true;
01754	        else
01755	            AloneRun = false;
01756	    }
01757	
01758	    //--------------------------------------------------------------
01759	
01760	begin :
01761	
01762	      if( WaitToStart )
01763	      {
01764	          Sleep( TimeToWaitBeforeStart + Rand( 3-Skill )*0.5 );
01765	          WaitToStart = false;
01766	      }
01767	
01768	      if( TeamStatus == cAttackStatus )
01769	      {
01770	          if( ShouldTakeTheBomb( Pawn ) )
01771	          {
01772	                if( DBugBot )
01773	                    Log("---> TakeMyBomb");
01774	
01775	                Goto('TakeMyBomb');
01776	          }
01777	          else
01778	          {
01779	                if( DBugBot )
01780	                    Log("---> WaitRestOfTheTeam");
01781	
01782	                Goto('WaitRestOfTheTeam');
01783	          }
01784	      }
01785	      else
01786	          RemoveOrder( Order_WaitToStart );
01787	
01788	
01789	    //--------------------------------------------------------------
01790	
01791	WaitRestOfTheTeam:
01792	
01793	    AloneOrNot();
01794	
01795	    if( AloneRun )
01796	        Goto('ForcedGoJump');
01797	
01798	    FindAttackSpot();
01799	
01800	    if( AttackPoint != none )
01801	    {
01802	        AttackPathNode(AttackPoint).Closed = true;
01803	
01804	        while( true )
01805	        {
01806	            NavPathStorage(AttackPoint);
01807	
01808	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01809	            {
01810	                MoveTarget = PathCache[ PathIndex ];
01811	                Focus=MoveTarget;
01812	
01813	                if( FireMvt )
01814	                    MoveToward( MoveTarget, Enemy , MoveSpeed );
01815	                else
01816	                    MoveToward( MoveTarget, Focus , MoveSpeed );
01817	            }
01818	
01819	            if( FullPath )
01820	                break;
01821	        }
01822	    }
01823	
01824	    if( DBugBot )
01825	        Log("---> Ready !");
01826	
01827	    if( AllReady() )
01828	    {
01829	        if( StorageObj.TheBombPick.ReadyToPickUp(0) )
01830	        {
01831	            if( DBugBot )
01832	                Log("---> Oups ! The Bomb --> TakeMyBomb");
01833	
01834	            Sleep( 0.2 + FRand() );
01835	            AttackPathNode(AttackPoint).Closed = false;
01836	
01837	            Goto('TakeMyBomb');
01838	        }
01839	    }
01840	
01841	    ReadyForNextAttackPoint=true;
01842	
01843	    Pawn.ControllerPitch = 0;
01844	
01845	    Pawn.velocity=vect(0,0,0);
01846	    Pawn.acceleration=vect(0,0,0);
01847	    Focus = none;
01848	    FocalPoint = vector(AttackPoint.Rotation)+Pawn.Location;
01849	
01850	    if( AttackPathNode(AttackPoint).MustBeCrouched )
01851	    {
01852	        Pawn.ShouldCrouch( true );
01853	    }
01854	    else if( AttackPathNode(AttackPoint).DoNotCrouch )
01855	    {
01856	        Pawn.ShouldCrouch( false );
01857	    }
01858	    else if( Rand( 100 ) < 20 + Skill*20 )
01859	    {
01860	        Pawn.ShouldCrouch( true );
01861	    }
01862	    else
01863	        Pawn.ShouldCrouch( false );
01864	
01865	    Pawn.SpineYawControl(true,3000, 1.2);
01866	
01867	ForcedGoJump:
01868	
01869	    while( true )
01870	    {
01871	        if( AllReady() )
01872	        {
01873	            Sleep( 1.0 + FRand() );
01874	
01875	            ReadyForNextAttackPoint=false;
01876	            Pawn.SpineYawControl(false,3000, 1.2);
01877	            Pawn.ShouldCrouch( false );
01878	            AttackPathNode(AttackPoint).Closed = false;
01879	
01880	            RemoveOrder( Order_WaitToStart );
01881	        }
01882	        else
01883	            Sleep( 0.5 );
01884	    }
01885	
01886	    //--------------------------------------------------------------
01887	
01888	TakeMyBomb:
01889	
01890	    Pawn.ShouldCrouch( false );
01891	
01892	    Item = StorageObj.TheBombPick;
01893	
01894	    if( ( Item == none ) || ( ! PickUp(Item).ReadyToPickUp(0) ) )
01895	    {
01896	        Sleep( 0.5 );
01897	        RemoveOrder( Order_TakeTheBomb );
01898	    }
01899	    else
01900	    {
01901	        while( true )
01902	        {
01903	            PickUpPathStorage(Item);
01904	
01905	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01906	            {
01907	                MoveTarget = PathCache[ PathIndex ];
01908	                Focus=MoveTarget;
01909	
01910	                MoveToward( MoveTarget, Focus , MoveSpeed );
01911	            }
01912	
01913	            if( FullPath )
01914	                break;
01915	        }
01916	
01917	        if( DBugBot )
01918	            Log("---> WaitRestOfTheTeam");
01919	
01920	        Goto('WaitRestOfTheTeam');
01921	    }
01922	}
01923	
01924	
01925	//__________________________________________________________________
01926	//__________________________________________________________________
01927	//                            AntiBug
01928	//__________________________________________________________________
01929	//__________________________________________________________________
01930	
01931	state AntiBug
01932	{
01933	    event BeginState()
01934	    {
01935	        if( DBugBot )
01936	        {
01937	            Log("");
01938	            Log("[ BOT"@ID@"] : *STATE* ---> AntiBug");
01939	        }
01940	    }
01941	}
01942	
01943	//__________________________________________________________________
01944	//__________________________________________________________________
01945	//                            Dead
01946	//__________________________________________________________________
01947	//__________________________________________________________________
01948	
01949	state Dead
01950	{
01951	    event BeginState()
01952	    {
01953	        super.BeginState();
01954	        WaitToStart = true;
01955	    }
01956	}
01957	
01958	//__________________________________________________________________
01959	//__________________________________________________________________
01960	//                            Kill
01961	//__________________________________________________________________
01962	//__________________________________________________________________
01963	
01964	state Kill
01965	{
01966	    event EnemyNotVisible()
01967	    {
01968	        if( WaitBeforeFire )
01969	            return;
01970	
01971	        if( Pawn.bIsCrouched )
01972	            Pawn.ShouldCrouch( false );
01973	
01974	        SetTimer(0.0,false);
01975	        SetTimer2(0.0,false);
01976	
01977	        bFireMove = false;
01978	        NbStraffe = 0;
01979	
01980	        if( IsInBombArea( Enemy ) )
01981	        {
01982	            bFire=0;
01983	            AddOrder( 70 ,Order_Seek,"Seek", 0);
01984	            RemoveOrder( Order_Kill );
01985	        }
01986	        else
01987	        {
01988	            bFire=0;
01989	            Enemy = none;
01990	
01991	            RemoveOrder( Order_Kill );
01992	        }
01993	    }
01994	}
01995	
01996	//__________________________________________________________________
01997	//__________________________________________________________________
01998	//                            CoverFight
01999	//__________________________________________________________________
02000	//__________________________________________________________________
02001	
02002	state CoverFight
02003	{
02004	    event BeginState()
02005	    {
02006	        if( DBugBot )
02007	        {
02008	            Log("");
02009	            Log("[ BOT"@ID@"] : *STATE* ---> CoverFight");
02010	            Log("    > Enemy :"@Enemy);
02011	        }
02012	
02013	        if( Enemy == Pawn )
02014	        {
02015	            Enemy = none ;
02016	            RemoveOrder( Order_CoverFight );
02017	        }
02018	
02019	        Focus = Enemy;
02020	        Pawn.velocity=vect(0,0,0);
02021	        Pawn.acceleration=vect(0,0,0);
02022	        InitShotError(false);
02023	
02024	        if( Pawn.WeaponMode == 'FM_Snipe' )
02025	        {
02026	            SetTimer( 0.5 + FRand(), false );
02027	        }
02028	        else
02029	            SetTimer( (4-Skill)*0.2+FRand()/2 ,False );
02030	    }
02031	
02032	    //--------------------------------------------------------------
02033	
02034	    event EndState()
02035	    {
02036	        bFire=0;
02037	        SetTimer(0.0,false);
02038	        SetTimer2(0.0,false);
02039	
02040	        if (pawn!=none) Pawn.Weapon.ForceReload();
02041	    }
02042	
02043	    //--------------------------------------------------------------
02044	
02045	    event SeePlayer( Pawn Seen )
02046	    {
02047	        if( ! IsEnemy( Seen ) )
02048	            return;
02049	
02050	        else if( ( IsNearest( Enemy,Seen) ) || ( ! CoverFightOrKill( Seen ) ) )
02051	        {
02052	            Enemy = Seen;
02053	
02054	            if( !FindOrder( Order_Kill ) )
02055	                AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
02056	
02057	            RemoveOrder( Order_CoverFight );
02058	        }
02059	    }
02060	
02061	    //--------------------------------------------------------------
02062	
02063	    event EnemyNotVisible()
02064	    {
02065	        if( bFireMove )
02066	        {
02067	            bFire=0;
02068	
02069	            SetTimer(0.0,false);
02070	            SetTimer2(0.0,false);
02071	        }
02072	        else
02073	        {
02074	            bFire=0;
02075	            Enemy = none;
02076	
02077	            RemoveOrder( Order_CoverFight );
02078	        }
02079	    }
02080	
02081	    //--------------------------------------------------------------
02082	
02083	    function SomeoneWantKillMe( Pawn Agressor )
02084	    {
02085	        bFireMove = true;
02086	
02087	        if( Agressor == Enemy )
02088	            return;
02089	
02090	        SeePlayer( Agressor );
02091	    }
02092	
02093	    //--------------------------------------------------------------
02094	
02095	Begin:
02096	
02097	
02098	    while( true )
02099	    {
02100	        Sleep( ( 4-skill)*StraffeDelay );
02101	
02102	        if( bFireMove )
02103	        {
02104	            if( ( ! Pawn.bIsCrouched ) && ( Rand( 100 ) < (Skill+1)*25 ) )
02105	                Pawn.ShouldCrouch( true );
02106	
02107	            Sleep( 1.0 + FRand() );
02108	
02109	            if( DefensePathNode(DefendPoint).MustBeCrouched )
02110	            {
02111	                Pawn.ShouldCrouch( true );
02112	            }
02113	            else if( DefensePathNode(DefendPoint).DoNotCrouch )
02114	            {
02115	                Pawn.ShouldCrouch( false );
02116	            }
02117	            else if( Rand( 100 ) < 20 + Skill*20 )
02118	            {
02119	                Pawn.ShouldCrouch( true );
02120	            }
02121	            else
02122	                Pawn.ShouldCrouch( false );
02123	
02124	            bFireMove=false;
02125	        }
02126	    }
02127	}
02128	
02129	//__________________________________________________________________
02130	//__________________________________________________________________
02131	//                            Seek
02132	//__________________________________________________________________
02133	//__________________________________________________________________
02134	
02135	state Seek
02136	{
02137	    event BeginState()
02138	    {
02139	        MaxSeekTime = 5;
02140	        super.BeginState();
02141	    }
02142	}
02143	
02144	//__________________________________________________________________
02145	//__________________________________________________________________
02146	//                            GoToAttackSpot
02147	//__________________________________________________________________
02148	//__________________________________________________________________
02149	
02150	state GoToAttackSpot
02151	{
02152	    event BeginState()
02153	    {
02154	        local int loop;
02155	
02156	        if( DBugBot )
02157	        {
02158	            Log("");
02159	            Log("[ BOT"@ID@"] : *STATE* ---> Go To Attack Spot");
02160	        }
02161	
02162	        Enemy = none;
02163	        Pawn.ControllerPitch = 0;
02164	        Pawn.ShouldCrouch( false );
02165	
02166	        if( StorageObj.CurrentAttackSpot[ SubTeamID ] == -1 )
02167	            ChooseAttackSpot();
02168	
02169	        AttackPhaseNumber = StorageObj.Possibility.Length;
02170	
02171	        if( ! ForceContinueAttackPhase )
02172	            AttackPhaseIndex = 0;
02173	
02174	        bFire=0;
02175	        FireMvt=false;
02176	        SetTimer(0.0,false);
02177	        SetTimer2(0.0,false);
02178	
02179	        Pawn.Weapon.ForceReload();
02180	
02181			if( DBugBot )
02182			{
02183	        log("");
02184	        log("--------------------------------------------------");
02185	        log(" > Attack Spot N"$StorageObj.CurrentAttackSpot[ SubTeamID ]+1);
02186	        log("   > AttackPhaseNumber:"@AttackPhaseNumber);
02187	
02188	        for( Loop=0 ; loop < StorageObj.Possibility.Length ; loop++ )
02189	        log("   >"@StorageObj.Possibility[Loop]);
02190	        log("--------------------------------------------------");
02191	        log("");
02192			}
02193	    }
02194	
02195	    //--------------------------------------------------------------
02196	
02197	    event EndState()
02198	    {
02199	        if (pawn!=none)
02200				{
02201					Pawn.SpineYawControl(false,3000, 1.2);
02202					Pawn.ShouldCrouch( false );
02203					AttackPathNode(AttackPoint).Closed = false;
02204			  }
02205	        if( FireMvt )
02206	        {
02207	            Enemy = none;
02208	
02209	            bFire=0;
02210	            FireMvt=false;
02211	            SetTimer(0.0,false);
02212	            SetTimer2(0.0,false);
02213	
02214	            if (pawn!=none) Pawn.Weapon.ForceReload();
02215	        }
02216	
02217	        if( FindOrder( Order_Kill ) )
02218	            ForceContinueAttackPhase = true;
02219	        else
02220	            ForceContinueAttackPhase = false;
02221	    }
02222	
02223	    //--------------------------------------------------------------
02224	
02225	    function FindAttackSpot()
02226	    {
02227	        local Array<NavigationPoint> UseablePoint;
02228	        local int Loop;
02229	        local NavigationPoint TmpNode;
02230	
02231	        for( Loop=0; Loop<AttackPointList.Length ; Loop++ )
02232	        {
02233	            TmpNode = AttackPointList[Loop];
02234	
02235	            if( (!AttackPathNode(TmpNode).Closed ) && ( AttackPathNode(TmpNode).Group == StorageObj.Possibility[ AttackPhaseIndex ] ) )
02236	            {
02237	                UseablePoint.Length = UseablePoint.Length+1;
02238	                UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
02239	            }
02240	        }
02241	
02242	        if( UseablePoint.Length != 0 )
02243	            AttackPoint = UseablePoint[ Rand(UseablePoint.Length) ];
02244	        else
02245	            AttackPoint = none;
02246	    }
02247	
02248	    //--------------------------------------------------------------
02249	
02250	    function SomeoneWantKillMe( Pawn Agressor )
02251	    {
02252	        if( Agressor == Pawn )
02253	            return;
02254	
02255	        SeePlayer( Agressor );
02256	    }
02257	
02258	    //--------------------------------------------------------------
02259	
02260	    event SeePlayer( Pawn Seen )
02261	    {
02262	        if( ( ( ! IsEnemy( Seen ) ) || DamnedImFlashed ) || ( ! IsShootable( Seen ) ) )
02263	            return;
02264	
02265	        if( Enemy == none )
02266	        {
02267	            Enemy = Seen;
02268	
02269	            if( FullPath && ( PathIndex > PathCacheSize -3 ) )
02270	            {
02271	                FireMvt=true;
02272	                SetTimer( (4-Skill)*0.2+FRand()/2 ,False );
02273	                Focus = Enemy;
02274	            }
02275	            else
02276	            {
02277	                if (DefendPoint!=none) DefensePathNode(DefendPoint).Closed = false;
02278	
02279	                if( !FindOrder( Order_Kill ) )
02280	                    AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
02281	            }
02282	        }
02283	    }
02284	
02285	    //--------------------------------------------------------------
02286	
02287	    event EnemyNotVisible()
02288	    {
02289	        if( FireMvt )
02290	        {
02291	            Enemy = none;
02292	
02293	            bFire=0;
02294	            FireMvt=false;
02295	            SetTimer(0.0,false);
02296	            SetTimer2(0.0,false);
02297	
02298	            Pawn.Weapon.ForceReload();
02299	        }
02300	    }
02301	
02302	    //--------------------------------------------------------------
02303	
02304	    function bool AllReady()
02305	    {
02306	        local int Loop , NbReady , NbBot;
02307	
02308	        for( Loop=0;Loop<MyTeam.Length;Loop++ )
02309	        {
02310	            if( ( MyTeam[ Loop ].AttackPhaseIndex == AttackPhaseIndex ) && ( MyTeam[ Loop ].IsInState('GoToAttackSpot' ) ) )
02311	            {
02312	                NbBot++;
02313	
02314	                if( MyTeam[ Loop ].ReadyForNextAttackPoint )
02315	                    NbReady++;
02316	            }
02317	
02318	        }
02319	
02320	        if( NbReady == NbBot )
02321	            return true;
02322	        else
02323	            return false;
02324	    }
02325	
02326	    //--------------------------------------------------------------
02327	
02328	    function AloneOrNot()
02329	    {
02330	        local int Loop , NbReady , NbBot;
02331	
02332	        for( Loop=0;Loop<MyTeam.Length;Loop++ )
02333	        {
02334	            if( ( MyTeam[ Loop ].AttackPhaseIndex == AttackPhaseIndex ) && ( MyTeam[ Loop ].IsInState('GoToAttackSpot' ) ) )
02335	                NbBot++;
02336	        }
02337	
02338	        if( NbBot == 0 )
02339	            AloneRun = true;
02340	        else
02341	            AloneRun = false;
02342	    }
02343	
02344	    //--------------------------------------------------------------
02345	
02346	Begin:
02347	
02348	    if( Pawn.Physics == PHYS_Falling )
02349	    {
02350	        while( true )
02351	        {
02352	            sleep( 0.1 );
02353	
02354	            if ( Pawn.Physics != PHYS_Falling )
02355	               break;
02356	        }
02357	    }
02358	
02359	    FindAttackSpot();
02360	
02361	    if( AttackPoint != none )
02362	    {
02363	        AttackPathNode(AttackPoint).Closed = true;
02364	
02365			if( DBugBot )
02366			{
02367	        Log("");
02368	        log("--- [ BOT"@ID@"] : GO"@StorageObj.Possibility[AttackPhaseIndex]@"("@AttackPoint@") ---");
02369			}
02370	
02371	        while( true )
02372	        {
02373	            NavPathStorage(AttackPoint);
02374	
02375	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02376	            {
02377	                MoveTarget = PathCache[ PathIndex ];
02378	                Focus=MoveTarget;
02379	
02380	                if( FireMvt )
02381	                    MoveToward( MoveTarget, Enemy , MoveSpeed );
02382	                else
02383	                    MoveToward( MoveTarget, Focus , MoveSpeed );
02384	            }
02385	
02386	            if( FullPath )
02387	                break;
02388	        }
02389	    }
02390	    else
02391	    {
02392	        RemoveOrder( Order_GoToAttackSpot );
02393	    }
02394	
02395	    ReadyForNextAttackPoint=true;
02396	
02397	    Pawn.ControllerPitch = 0;
02398	
02399	    Pawn.velocity=vect(0,0,0);
02400	    Pawn.acceleration=vect(0,0,0);
02401	    Focus = none;
02402	    FocalPoint = vector(AttackPoint.Rotation)+Pawn.Location;
02403	
02404	    if( AttackPathNode(AttackPoint).MustBeCrouched )
02405	    {
02406	        Pawn.ShouldCrouch( true );
02407	    }
02408	    else if( AttackPathNode(AttackPoint).DoNotCrouch )
02409	    {
02410	        Pawn.ShouldCrouch( false );
02411	    }
02412	    else if( Rand( 100 ) < 20 + Skill*20 )
02413	    {
02414	        Pawn.ShouldCrouch( true );
02415	    }
02416	    else
02417	        Pawn.ShouldCrouch( false );
02418	
02419	    Pawn.SpineYawControl(true,3000, 1.2);
02420	
02421	    GetAttackPointTime();
02422	
02423	    AloneOrNot();
02424	
02425	    if( ( AttackPointTime != 0 ) && ( ! AloneRun ) )
02426	        sleep( AttackPointTime );
02427	
02428	    while( true )
02429	    {
02430	        if( AllReady() )
02431	        {
02432	            if( ! AloneRun )
02433	                Sleep( 0.1 + FRand() );
02434	            else
02435	                Sleep( 1.0 );
02436	
02437	            ReadyForNextAttackPoint=false;
02438	            AttackPhaseIndex++;
02439	
02440	            if( AttackPhaseIndex == AttackPhaseNumber-1 )
02441	            {
02442	                if( BombCarrier( Pawn ) )
02443	                {
02444							if( DBugBot )
02445							{
02446	                    Log("");
02447	                    log("--- [ BOT"@ID@"] : GO TO BOMBSPOT ---");
02448							}
02449	                    Sleep( 3.0 + FRand() );
02450	                    AddOrder(78,Order_PutTheBomb,"Order_PutTheBomb",0);
02451	                }
02452	                else
02453	                {
02454						   if( DBugBot )
02455							{
02456	                    Log("");
02457	                    log("--- [ BOT"@ID@"] : COVER BOMBSPOT ---");
02458							}
02459	                    AddOrder(78,Order_CoverTheBomb,"CoverTheBomb",0);
02460	                }
02461	            }
02462	
02463	            Pawn.SpineYawControl(false,3000, 1.2);
02464	            Pawn.ShouldCrouch( false );
02465	            AttackPathNode(AttackPoint).Closed = false;
02466	            Goto('begin');
02467	        }
02468	        else
02469	            Sleep( 0.5 );
02470	    }
02471	}
02472	
02473	//__________________________________________________________________
02474	//__________________________________________________________________
02475	//                            TakeTheBomb
02476	//__________________________________________________________________
02477	//__________________________________________________________________
02478	
02479	state TakeTheBomb
02480	{
02481	    event BeginState()
02482	    {
02483	        if( DBugBot )
02484	        {
02485	            Log("");
02486	            Log("[ BOT"@ID@"] : *STATE* ---> Take The Bomb");
02487	        }
02488	
02489	        Enemy = none;
02490	        Pawn.ControllerPitch = 0;
02491	
02492	        Pawn.ShouldCrouch( false );
02493	    }
02494	
02495	    //--------------------------------------------------------------
02496	
02497	    event SeePlayer( Pawn Seen );
02498	
02499	    //--------------------------------------------------------------
02500	
02501	    function SomeoneWantKillMe( Pawn Agressor );
02502	
02503	    //--------------------------------------------------------------
02504	
02505	Begin:
02506	
02507	    Item = StorageObj.TheBombPick;
02508	
02509	    if( ( Item == none ) || ( ! PickUp(Item).ReadyToPickUp(0) ) )
02510	    {
02511	        Sleep( 0.5 );
02512	        RemoveOrder( Order_TakeTheBomb );
02513	    }
02514	    else
02515	    {
02516	        while( true )
02517	        {
02518	            PickUpPathStorage(Item);
02519	
02520	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02521	            {
02522	                MoveTarget = PathCache[ PathIndex ];
02523	                Focus=MoveTarget;
02524	
02525	                MoveToward( MoveTarget, Focus , MoveSpeed );
02526	            }
02527	
02528	            if( FullPath )
02529	                break;
02530	        }
02531	
02532	        RemoveOrder( Order_TakeTheBomb );
02533	    }
02534	}
02535	
02536	//__________________________________________________________________
02537	//__________________________________________________________________
02538	//                            PutTheBomb
02539	//__________________________________________________________________
02540	//__________________________________________________________________
02541	
02542	state PutTheBomb
02543	{
02544	    event BeginState()
02545	    {
02546	        if( DBugBot )
02547	        {
02548	            Log("");
02549	            Log("[ BOT"@ID@"] : *STATE* ---> Put The Bomb");
02550	        }
02551	
02552	        Enemy = none;
02553	        Pawn.ControllerPitch = 0;
02554	
02555	        Pawn.ShouldCrouch( false );
02556	    }
02557	
02558	    //--------------------------------------------------------------
02559	
02560	    event EndState()
02561	    {
02562	        bFire = 0;
02563	
02564	        SetTimer(0.0,false);
02565	        SetTimer2(0.0,false);
02566	        SetTimer3(0.0,false);
02567				if (pawn!=none)
02568				{
02569		        Pawn.ControllerPitch = 0;
02570	
02571		        Pawn.ShouldCrouch( false );
02572		        Pawn.SpineYawControl(false,3000, 1.2);
02573			  }
02574	        SwitchWeapon();
02575	    }
02576	
02577	    //--------------------------------------------------------------
02578	
02579	    event SeePlayer( Pawn Seen )
02580	    {
02581	        if( IsEnemy( Seen ) )
02582	            SomeoneWantKillMe( Seen );
02583	    }
02584	
02585	    //--------------------------------------------------------------
02586	
02587	    function SomeoneWantKillMe( Pawn Agressor )
02588	    {
02589	        local int Loop;
02590	
02591	        if( ! SubTeamInit )
02592	            InitializeSubTeam();
02593	
02594	        if( MyTeam.Length != 0 )
02595	        {
02596	            for( Loop=0;Loop<MyTeam.Length;Loop++ )
02597	            {
02598	                if( MyTeam[ Loop ].Enemy != Agressor )
02599	                    MyTeam[ Loop ].FocusFire( Agressor );
02600	            }
02601	        }
02602	
02603	        if( ( bFire == 1 ) && ( LatentFloat < 4.0 ) )
02604	            return;
02605	        else
02606	            global.SomeoneWantKillMe( Agressor );
02607	    }
02608	
02609	    //--------------------------------------------------------------
02610	
02611	    function Kassos()
02612	    {
02613	        local int Loop;
02614	        local float DistToTheBomb;
02615	
02616	        if( ! SubTeamInit )
02617	            InitializeSubTeam();
02618	
02619	        for( Loop=0;Loop<MyTeam.Length;Loop++ )
02620	        {
02621	            MyTeam[ Loop ].AddOrder(79,Order_BackToHomeBase,"BackToHomeBase",Order_CoverTheBomb);
02622	        }
02623	    }
02624	
02625	    //--------------------------------------------------------------
02626	
02627	Begin:
02628	
02629	    AttackPoint = BombPoint[ StorageObj.CurrentAttackSpot[ SubTeamID ] ];
02630	
02631	    while( true )
02632	    {
02633	        NavPathStorage(AttackPoint);
02634	
02635	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02636	        {
02637	            MoveTarget = PathCache[ PathIndex ];
02638	            Focus=MoveTarget;
02639	
02640	            MoveToward( MoveTarget, Focus , MoveSpeed );
02641	        }
02642	
02643	        if( FullPath )
02644	            break;
02645	
02646	        if( VSize( Pawn.Location - AttackPoint.Location ) < BombPoint[ StorageObj.CurrentAttackSpot[ SubTeamID ] ].CollisionRadius )
02647	            break;
02648	    }
02649	
02650	    Pawn.ControllerPitch = 0;
02651	
02652	    Pawn.velocity=vect(0,0,0);
02653	    Pawn.acceleration=vect(0,0,0);
02654	
02655	    Focus = none;
02656	    FocalPoint = vector(AttackPoint.Rotation)+Pawn.Location;
02657	
02658	    Pawn.ShouldCrouch( true );
02659	    Pawn.SpineYawControl(true,3000, 1.2);
02660	
02661	    Pawn.PendingWeapon = weapon(Pawn.FindInventoryType(class'MPBomb'));
02662	    Pawn.Weapon.PutDown();
02663	
02664	    sleep( 2.0 );
02665	
02666	    bFire=1;
02667	    Pawn.Weapon.Fire(0);
02668	
02669	    sleep(16.0);
02670	
02671	    Kassos();
02672	
02673	    AddOrder(79,Order_BackToHomeBase,"BackToHomeBase",Order_PutTheBomb);
02674	}
02675	
02676	//__________________________________________________________________
02677	//__________________________________________________________________
02678	//                            CoverTheBomb
02679	//__________________________________________________________________
02680	//__________________________________________________________________
02681	
02682	state CoverTheBomb
02683	{
02684	    event BeginState()
02685	    {
02686	        if( DBugBot )
02687	        {
02688	            Log("");
02689	            Log("[ BOT"@ID@"] : *STATE* ---> Cover The Bomb");
02690	        }
02691	
02692	        Enemy = none;
02693	        Pawn.ControllerPitch = 0;
02694	        Pawn.ShouldCrouch( false );
02695	    }
02696	
02697	    event EndState()
02698	    {
02699	        if (pawn!=none) Pawn.SpineYawControl(false,3000, 1.2);
02700	        AttackPathNode(AttackPoint).Closed = false;
02701	    }
02702	
02703	    //--------------------------------------------------------------
02704	
02705	    function FindAttackSpot()
02706	    {
02707	        local Array<NavigationPoint> UseablePoint;
02708	        local int Loop;
02709	        local NavigationPoint TmpNode;
02710	
02711	        for( Loop=0; Loop<AttackPointList.Length ; Loop++ )
02712	        {
02713	            TmpNode = AttackPointList[Loop];
02714	
02715	            if( ( ! AttackPathNode(TmpNode).Closed ) && ( AttackPathNode(TmpNode).Group == StorageObj.Possibility[ AttackPhaseIndex ] ) )
02716	            {
02717	                UseablePoint.Length = UseablePoint.Length+1;
02718	                UseablePoint[ UseablePoint.Length-1 ] = TmpNode;
02719	            }
02720	        }
02721	
02722	        if( UseablePoint.Length != 0 )
02723	            AttackPoint = UseablePoint[ Rand(UseablePoint.Length) ];
02724	        else
02725	            AttackPoint = none;
02726	    }
02727	
02728	    //--------------------------------------------------------------
02729	
02730	Begin:
02731	
02732	    FindAttackSpot();
02733	
02734	    if( AttackPoint != none )
02735	    {
02736	        AttackPathNode(AttackPoint).Closed = true;
02737	
02738	        while( true )
02739	        {
02740	            NavPathStorage(AttackPoint);
02741	
02742	            for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02743	            {
02744	                MoveTarget = PathCache[ PathIndex ];
02745	                Focus=MoveTarget;
02746	
02747	                MoveToward( MoveTarget, Focus , MoveSpeed );
02748	            }
02749	
02750	            if( FullPath )
02751	                break;
02752	
02753	            if( VSize( Pawn.Location - AttackPoint.Location ) < BombPoint[ StorageObj.CurrentAttackSpot[ SubTeamID ] ].CollisionRadius )
02754	                break;
02755	        }
02756	
02757	        Pawn.velocity=vect(0,0,0);
02758	        Pawn.acceleration=vect(0,0,0);
02759	        Focus = none;
02760	        FocalPoint = vector(AttackPoint.Rotation)+Pawn.Location;
02761	
02762	        if( AttackPathNode(AttackPoint).MustBeCrouched )
02763	        {
02764	            Pawn.ShouldCrouch( true );
02765	        }
02766	        else if( AttackPathNode(AttackPoint).DoNotCrouch )
02767	        {
02768	            Pawn.ShouldCrouch( false );
02769	        }
02770	        else if( Rand( 100 ) < 20 + Skill*20 )
02771	        {
02772	            Pawn.ShouldCrouch( true );
02773	        }
02774	        else
02775	            Pawn.ShouldCrouch( false );
02776	
02777	        Pawn.SpineYawControl(true,3000, 1.2);
02778	    }
02779	}
02780	
02781	//__________________________________________________________________
02782	
02783	
02784	
02785	defaultproperties
02786	{
02787	     BombSpotStatus(0)=1
02788	     BombSpotStatus(1)=1
02789	     BombSpotStatus(2)=1
02790	     TeamStatus=1
02791	     TotalDefendTime=-1.000000
02792	     TotalMaxDefendTime=40.000000
02793	     WaitToStart=True
02794	     TimeToWaitBeforeStart=2.000000
02795	}

End Source Code