XIIIMP
Class CTFBotController

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

class CTFBotController
extends XIIIMP.TeamBotController

//----------------------------------------------------------- // //-----------------------------------------------------------
Variables
 Array BackPointList
 bool DontChangeTactikalPoint
 Array GoPointList
 Array GuardPointList
 NavigationPoint HidePoint,TacticalPoint
 Array HideSpotList
 bool JustRespawn
 NavigationPoint LastGoPointUsed,LastBackPointUsed
 float LastSeeTime
 float LastTestTime
 ProtectTime, MaxProtectTime
 XIIIMPFlag MyFlag,EnemyFlag
 bool NearTheFlag
 bool ReadyToAttack
 bool SeekAndFire
 bool StopProtect
 XIIIMPCTFStorage StorageObj
 Array WaitPointList

States
GameEnded, Dead, ProtectTheHolder, WaitBeforeAttack, Kill, SeekTheFlag, ProtectTheFlag, WaitToFlagComeBack, GoToSafePoint, BringBackTheFlag, CaptureTheFlag

Function Summary
 bool CanTryToHelp(TeamBotController Bot)
     
//__________________________________________________________________
 void CatchFlag()
     
//__________________________________________________________________
 void FindTeamRole()
     
//__________________________________________________________________
 void FlagPathStorage(Actor Target)
     
//__________________________________________________________________
 void ForceOtherTeamBotToHelpTheFlagHolder()
     
//__________________________________________________________________
 void ForceTheBotToHelpTheHumanFlagHolder()
     
//__________________________________________________________________
 int GetFlagState(XIIIMPFlag F)
     
//__________________________________________________________________
 void GrenadPossibility(GrenadPathNode GrenadNode)
     
//__________________________________________________________________
 void InitPickUpList()
     
//__________________________________________________________________
 void UpDateOrder(int OldOrder, int NewOrder)
     
//__________________________________________________________________


State GameEnded Function Summary
 void UpDateOrder(int OldOrder, int NewOrder)


State Dead Function Summary


State ProtectTheHolder Function Summary
 bool StopOrder()
     
//--------------------------------------------------------------
 void FindPathToMyLeader()
     
//--------------------------------------------------------------
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------
 void forceOtherTeamBotToHelpProtector()
     
//--------------------------------------------------------------


State WaitBeforeAttack Function Summary
 bool AllReady()
     
//--------------------------------------------------------------
 bool StopOrder()
     
//--------------------------------------------------------------
 void GetRandomWaitPoint()
     
//--------------------------------------------------------------


State Kill Function Summary
 int GetLifePriority()
     
//--------------------------------------------------------------


State SeekTheFlag Function Summary
 int GetLifePriority()
     
//--------------------------------------------------------------
 bool StopOrder()
     
//--------------------------------------------------------------


State ProtectTheFlag Function Summary
 bool StopOrder()
     
//--------------------------------------------------------------
 void GetRandomGuardPoint()
     
//--------------------------------------------------------------


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


State GoToSafePoint Function Summary
 bool StopOrder()
     
//--------------------------------------------------------------
 void GetRandomBackPoint()
     
//--------------------------------------------------------------
 void GetRandomSafePoint()
     
//--------------------------------------------------------------
 int GetLifePriority()
     
//--------------------------------------------------------------
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------
 float DistToMyFlag()
     
//--------------------------------------------------------------


State BringBackTheFlag Function Summary
 bool SkipTacticalPoint()
     
//--------------------------------------------------------------
 bool StopOrder()
     
//--------------------------------------------------------------
 void GetRandomBackPoint()
     
//--------------------------------------------------------------
 int GetLifePriority()
     
//--------------------------------------------------------------
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------
 float DistToMyFlag()
     
//--------------------------------------------------------------


State CaptureTheFlag Function Summary
 bool SkipTacticalPoint()
     
//--------------------------------------------------------------
 void SomeoneWantKillMe(Pawn Agressor)
     
//--------------------------------------------------------------
 float DistToTheEnemyFlag()
     
//--------------------------------------------------------------
 int GetLifePriority()
     
//--------------------------------------------------------------
 void GetRandomGoPoint()
     
//--------------------------------------------------------------



Source Code


00001	//-----------------------------------------------------------
00002	//
00003	//-----------------------------------------------------------
00004	class CTFBotController extends TeamBotController;
00005	
00006	var XIIIMPFlag MyFlag,EnemyFlag;
00007	var Array<NavigationPoint> HideSpotList;
00008	var Array<NavigationPoint> GoPointList;
00009	var Array<NavigationPoint> BackPointList;
00010	var Array<NavigationPoint> GuardPointList;
00011	var Array<NavigationPoint> WaitPointList;
00012	var NavigationPoint HidePoint,TacticalPoint;
00013	var int GoPhase,BackPhase,MaxHideTime,HideTime , ProtectTime, MaxProtectTime;
00014	var NavigationPoint LastGoPointUsed,LastBackPointUsed;
00015	var bool StopProtect;
00016	var bool JustRespawn;
00017	var bool ReadyToAttack;
00018	var XIIIMPCTFStorage StorageObj;
00019	var bool SeekAndFire;
00020	var float LastSeeTime;
00021	var bool NearTheFlag;
00022	var bool DontChangeTactikalPoint;
00023	var float LastTestTime;
00024	
00025	
00026	const Order_CaptureTheFlag    = 1024;
00027	const Order_ProtectTheFlag    = 2048;
00028	const Order_SeekTheFlag       = 4096;
00029	const Order_BringBackTheFlag  = 8192;
00030	const Order_GoToSafePoint     = 16384;
00031	const Order_WaitToFlagComeBack= 32768;
00032	const Order_WaitBeforeAttack  = 8388608;
00033	const Order_ProtectTheHolder  = 16777216; //24
00034	
00035	const cAttack = 0;
00036	const cDefense = 1;
00037	const cSupport = 2;
00038	
00039	const cHome = 0;
00040	const cHeld = 1;
00041	const cDropped = 2;
00042	
00043	
00044	//__________________________________________________________________
00045	
00046	function bool CanTryToHelp(TeamBotController Bot)
00047	{
00048	    if( Bot.Enemy != none )
00049	        return false;
00050	
00051	    if( Bot.IsInState('Dead') || Bot.IsInState('GameEnded') )
00052	        return false;
00053	    else if( Bot.IsInState('BringBackTheFlag') || Bot.IsInState('GoToSafePoint') )
00054	        return false;
00055	    else if( Bot.IsInState('WaitToFlagComeBack') )
00056	        return false;
00057	    else
00058	        return true;
00059	}
00060	
00061	//__________________________________________________________________
00062	
00063	function GrenadPossibility( GrenadPathNode GrenadNode )
00064	{
00065	    if( GrenadNode.Team != TeamID )
00066	        return;
00067	
00068	    if( ! IsInState('CaptureTheFlag') )
00069	        return;
00070	
00071	    super.GrenadPossibility( GrenadNode );
00072	}
00073	
00074	//__________________________________________________________________
00075	
00076	function UpDateOrder(int OldOrder,int NewOrder)
00077	{
00078	    if( DBugBot )
00079	    {
00080	        Log("");
00081	        Log("[ BOT"@ID@"] : UpDateOrder Role"@TeamRole@"->"@NewOrder);
00082	    }
00083	
00084	    if( NewOrder == TeamRole )
00085	        return;
00086	
00087	    TeamRole = NewOrder;
00088	
00089	
00090	    if( Pawn == EnemyFlag.Holder )
00091	    {
00092	        if( DBugBot )
00093	            Log(" > Disable, bring back the flag !");
00094	
00095	        return;
00096	    }
00097	
00098	    LastDefaultOrderTime=0;
00099	    ClearAllOrders();
00100	}
00101	
00102	//__________________________________________________________________
00103	
00104	event Timer()
00105	{
00106	    if( MyWeaponIsAGrenad )
00107	    {
00108	        bFire=1;
00109	        Pawn.Weapon.Fire(0);
00110	        bFire=0;
00111	
00112	        SetTimer2(0.5,false);
00113	        SetTimer(0.0,false);
00114	    }
00115	    else if( XIIIWeapon(Pawn.Weapon).WeaponMode == WM_SemiAuto )
00116	    {
00117	        bFire=1;
00118	        Pawn.Weapon.Fire(0);
00119	        bFire=0;
00120	
00121	        SetTimer2( XIIIWeapon(Pawn.Weapon).ShotTime + ( 3 - Skill )*0.25,false );
00122	        SetTimer(0.0,false);
00123	    }
00124	    else if ( ( ( XIIIPawn(Pawn).WeaponMode == 'FM_M16' ) && ( XIIIWeapon(Pawn.Weapon).HasAltAmmo() ) ) && ( VSize( Enemy.Location - Pawn.Location ) < 1600 ) )
00125	    {
00126	        bFire=1;
00127	        Pawn.Weapon.AltFire(0);
00128	        bFire=0;
00129	
00130	        SetTimer2( 0.5,false );
00131	        SetTimer(0.0,false);
00132	    }
00133	    else
00134	    {
00135	        bFire=1;
00136	        Pawn.Weapon.Fire(0);
00137	
00138	        SetTimer2( 2.5 - skill/2,false );
00139	        SetTimer(0.0,false);
00140	    }
00141	}
00142	
00143	//__________________________________________________________________
00144	
00145	event Timer2()
00146	{
00147	    if( MyWeaponIsAGrenad )
00148	    {
00149	        Pawn.Weapon.AIRating = 0.11;
00150	        SwitchWeapon();
00151	        SetTimer(1.0,false);
00152	        SetTimer2(0.0,false);
00153	    }
00154	    else if( XIIIWeapon(Pawn.Weapon).WeaponMode == WM_SemiAuto )
00155	    {
00156	        if( XIIIPawn(Pawn).WeaponMode == 'FM_Snipe' )
00157	            SetTimer(0.01 + FRand()/2,false);
00158	        else
00159	            SetTimer(0.01,false);
00160	
00161	        SetTimer2(0.0,false);
00162	    }
00163	    else if ( ( ( XIIIPawn(Pawn).WeaponMode == 'FM_M16' ) && ( XIIIWeapon(Pawn.Weapon).HasAltAmmo() ) ) && ( VSize( Enemy.Location - Pawn.Location ) < 1600 ) )
00164	    {
00165	        SetTimer(0.1,false);
00166	        SetTimer2(0.0,false);
00167	    }
00168	    else
00169	    {
00170	        bFire=0;
00171	        SetTimer(0.01,false);
00172	        SetTimer2(0.0,false);
00173	    }
00174	
00175	    if( ! Pawn.Weapon.HasAmmo() )
00176	        SwitchWeapon();
00177	
00178	    if( ( Enemy == none ) || ( Enemy.bIsDead ) )
00179	    {
00180	        bFire=0;
00181	        Enemy = none;
00182	        Pawn.ControllerPitch = 0;
00183	        SeekAndFire=false;
00184	        SetTimer(0.0,false);
00185	        SetTimer2(0.0,false);
00186	
00187	        if( IsInState('Kill') )
00188	            RemoveOrder( Order_Kill );
00189	    }
00190	}
00191	
00192	//__________________________________________________________________
00193	
00194	function CatchFlag()
00195	{
00196	    if( GetFlagState( MyFlag ) == cHome )
00197	    {
00198	        BackPhase = 0;
00199	        AddOrder( 75 , Order_BringBackTheFlag , "BringBackTheFlag",0);
00200	    }
00201	    else
00202	    {
00203	        BackPhase = 0;
00204	        AddOrder( 75 , Order_GoToSafePoint , "Go To Safe Point",0);
00205	    }
00206	
00207	    if( FindOrder( Order_CaptureTheFlag ) )
00208	        RemoveOrder( Order_CaptureTheFlag );
00209	
00210	    ForceOtherTeamBotToHelpTheFlagHolder();
00211	}
00212	
00213	//__________________________________________________________________
00214	
00215	function ForceOtherTeamBotToHelpTheFlagHolder()
00216	{
00217	    local int Loop;
00218	
00219	    for( Loop=0;Loop<MyTeam.Length;Loop++ )
00220	    {
00221	        if( ( MyTeam[ Loop ].TeamRole != cDefense ) && ( ! MyTeam[ Loop ].IsInState('Dead') ) )
00222	        {
00223	            MyTeam[ Loop ].LastDefaultOrderTime=0;
00224	
00225	            if( ! MyTeam[ Loop ].FindOrder( Order_ProtectTheHolder ) )
00226	            {
00227	                MyTeam[ Loop ].Leader = EnemyFlag.Holder;
00228	                MyTeam[ Loop ].AddOrder( 65,Order_ProtectTheHolder,"Protect The Holder",0);
00229	            }
00230	        }
00231	        else if( ( MyTeam[ Loop ].TeamRole == cDefense ) && ( FindOrder( Order_CaptureTheFlag ) ) )
00232	        {
00233	            RemoveOrder( Order_CaptureTheFlag );
00234	        }
00235	    }
00236	}
00237	
00238	//__________________________________________________________________
00239	
00240	function ForceTheBotToHelpTheHumanFlagHolder()
00241	{
00242	    if( ( TeamRole != cDefense ) && ( ! IsInState('Dead') ) )
00243	    {
00244	        LastDefaultOrderTime=0;
00245	
00246	        if( ! FindOrder( Order_ProtectTheHolder ) )
00247	        {
00248	            Leader = EnemyFlag.Holder;
00249	            AddOrder( 65,Order_ProtectTheHolder,"Protect The Holder",0);
00250	        }
00251	    }
00252	    else if( ( TeamRole == cDefense ) && ( FindOrder( Order_CaptureTheFlag ) ) )
00253	    {
00254	        RemoveOrder( Order_CaptureTheFlag );
00255	    }
00256	}
00257	
00258	//__________________________________________________________________
00259	
00260	function FindTeamRole()
00261	{
00262	    local int Loop,BestLevel,SecondBestLevel,WorstLevel;
00263	    local CTFBotController Best,SecondBest,Worst;
00264	    local Array<CTFBotController> TmpTeam;
00265	    local CTFBotController Bot;
00266	
00267	
00268	//    TeamRole = cDefense;
00269	//    return;
00270	
00271	
00272	    foreach DynamicActors(class'CTFBotController', BOT)
00273	    {
00274	        if( Bot.TeamID == TeamID )
00275	        {
00276	            TmpTeam.Length = TmpTeam.Length+1;
00277	            TmpTeam[ TmpTeam.Length-1 ] = BOT;
00278	        }
00279	    }
00280	
00281	
00282	    for( Loop=0;Loop<TmpTeam.Length;Loop++)
00283	    {
00284	        if( ( TmpTeam[Loop].Skill > BestLevel ) || ( Best == none ) )
00285	        {
00286	            BestLevel = TmpTeam[Loop].Skill;
00287	            Best = TmpTeam[Loop];
00288	        }
00289	    }
00290	
00291	    if( Best == self )
00292	    {
00293	        TeamRole = cAttack;
00294	        return;
00295	    }
00296	
00297	    for( Loop=0;Loop<TmpTeam.Length;Loop++)
00298	    {
00299	        if( ( TmpTeam[Loop].Skill > SecondBestLevel ) || ( SecondBest == none ) )
00300	        {
00301	            if( TmpTeam[Loop] != Best )
00302	            {
00303	                SecondBestLevel = TmpTeam[Loop].Skill;
00304	                SecondBest = TmpTeam[Loop];
00305	            }
00306	        }
00307	    }
00308	
00309	    if( SecondBest == self )
00310	    {
00311	        TeamRole = cDefense;
00312	        return;
00313	    }
00314	
00315	    for( Loop=0;Loop<TmpTeam.Length;Loop++)
00316	    {
00317	        if( ( TmpTeam[Loop].Skill < WorstLevel ) || ( Worst == none ) )
00318	        {
00319	            if( ( TmpTeam[Loop] != Best ) && ( TmpTeam[Loop] != SecondBest ) )
00320	            {
00321	                WorstLevel = TmpTeam[Loop].Skill;
00322	                Worst = TmpTeam[Loop];
00323	            }
00324	        }
00325	    }
00326	
00327	    if( Worst == self )
00328	    {
00329	        TeamRole = cDefense;
00330	        return;
00331	    }
00332	
00333	    TeamRole = cAttack;
00334	}
00335	
00336	
00337	//__________________________________________________________________
00338	
00339	function InitPickUpList()
00340	{
00341	    local PickUp A;
00342	    local NavigationPoint Nav;
00343	    local Pawn P;
00344	    local TeamBotController Bot;
00345	    local int Loop;
00346	//    local XIIIMPBotInteraction BI;
00347		local Controller C;
00348		local XIIIMPFlag TmpFlag;
00349	    local XIIIMPWatchPoint Watch;
00350	
00351	    bInitPickUpList = true;
00352	
00353	
00354	    foreach AllActors(class'XIIIMPWatchPoint', Watch)
00355	    {
00356	        WatchPointList.Length = WatchPointList.Length+1;
00357	        WatchPointList[ WatchPointList.Length-1 ] = Watch;
00358	    }
00359	
00360	
00361	//	for ( C=Level.ControllerList; C!=None; C= C.NextController )
00362	//	{
00363	//		  if( XIIIMPPlayerController(C) != none )
00364	//        {
00365	//            if( C.PlayerReplicationInfo.Team.TeamIndex == TeamID )
00366	//            {
00367	//                BI = XIIIMPBotInteraction(XIIIMPPlayerController(C).MyInteraction );
00368	//                BI.BotControllerList.Length = BI.BotControllerList.Length+1;
00369	//                BI.BotControllerList[ BI.BotControllerList.Length-1 ] = self;
00370	//            }
00371	//
00372	//            //break;   //FRD il  peut ya voir plusieurs players en splite
00373	//        }
00374	//	}
00375	
00376	
00377	    foreach DynamicActors(class'XIIIMPCTFStorage', StorageObj)
00378	    {
00379	        if( StorageObj.TeamId == TeamId )
00380	            break;
00381	    }
00382	
00383	    Nav = Level.NavigationPointList;
00384	
00385	    while( Nav != none)
00386	    {
00387	        if( SnipePathNode( Nav) != none )
00388	        {
00389	            if( ( ( SnipePathNode( Nav ).Team == TeamID ) || ( SnipePathNode( Nav ).Team == 2 ) ) && ( SnipePathNode( Nav).BotLevel <= Skill ) )
00390	            {
00391	                SnipeSpotList.Length = SnipeSpotList.Length+1;
00392	                SnipeSpotList[ SnipeSpotList.Length-1 ] = Nav;
00393	            }
00394	        }
00395	
00396	        if( SafePathNode( Nav) != none )
00397	        {
00398	            if( ( ( SafePathNode( Nav ).Team == TeamID ) || ( SafePathNode( Nav ).Team == 2 ) ) && ( SafePathNode( Nav).BotLevel <= Skill ) )
00399	            {
00400	                HideSpotList.Length = HideSpotList.Length+1;
00401	                HideSpotList[ HideSpotList.Length-1 ] = Nav;
00402	            }
00403	        }
00404	
00405	        if( GuardPathNode( Nav) != none )
00406	        {
00407	            if( ( ( GuardPathNode( Nav ).Team == TeamID ) || ( GuardPathNode( Nav ).Team == 2 ) ) && ( GuardPathNode( Nav).BotLevel <= Skill ) )
00408	            {
00409	                if( GuardPathNode( Nav ).CanBeUsedByTheAttackTeam )
00410	                {
00411	                    WaitPointList.Length = WaitPointList.Length+1;
00412	                    WaitPointList[ WaitPointList.Length-1 ] = Nav;
00413	                }
00414	                else
00415	                {
00416	                    GuardPointList.Length = GuardPointList.Length+1;
00417	                    GuardPointList[ GuardPointList.Length-1 ] = Nav;
00418	                }
00419	            }
00420	        }
00421	
00422	        if( TacticalPathNode( Nav) != none )
00423	        {
00424	            if( ( ( TacticalPathNode( Nav ).Team == TeamID ) || ( TacticalPathNode( Nav ).Team == 2 ) ) && ( TacticalPathNode( Nav).BotLevel <= Skill ) )
00425	            {
00426	                if( ( TacticalPathNode( Nav).Direction == 0 ) || ( TacticalPathNode( Nav).Direction == 2 ) )
00427	                {
00428	                    GoPointList.Length = GoPointList.Length+1;
00429	                    GoPointList[ GoPointList.Length-1 ] = Nav;
00430	                }
00431	
00432	                if( ( TacticalPathNode( Nav).Direction == 1 ) || ( TacticalPathNode( Nav).Direction == 2 ) )
00433	                {
00434	                    BackPointList.Length = BackPointList.Length+1;
00435	                    BackPointList[ BackPointList.Length-1 ] = Nav;
00436	                }
00437	            }
00438	        }
00439	
00440	        Nav = Nav.NextNavigationPoint;
00441	    }
00442	
00443	    if( ( WaitPointList.Length == 0 ) && ( GuardPointList.Length != 0 ) )
00444	    {
00445	        for( Loop=0;Loop<GuardPointList.Length;Loop++)
00446	        {
00447	            WaitPointList.Length = WaitPointList.Length+1;
00448	            WaitPointList[ WaitPointList.Length-1 ] = GuardPointList[Loop];
00449	        }
00450	    }
00451	
00452	    foreach DynamicActors(class'PickUp', A)
00453	    {
00454	        FullPickUpList.Length = FullPickUpList.Length+1;
00455	        FullPickUpList[ FullPickUpList.Length-1 ] = A;
00456	
00457	        if ( MultiPlayerMedPickUp(A) != none )
00458	        {
00459	            MedKitList.Length = MedKitList.Length+1;
00460	            MedKitList[ MedKitList.Length-1 ] = MultiPlayerMedPickUp(A);
00461	        }
00462	        else if( XIIIWeaponPickUp(A) != none )
00463	        {
00464	            WeaponList.Length = WeaponList.Length+1;
00465	            WeaponList[ WeaponList.Length-1 ] = XIIIWeaponPickUp(A);
00466	        }
00467	        else if( XIIIArmorPickUp(A) != none )
00468	        {
00469	            ArmorList.Length = ArmorList.Length+1;
00470	            ArmorList[ ArmorList.Length-1 ] = XIIIArmorPickUp(A);
00471	        }
00472	    }
00473	
00474	    foreach DynamicActors(class'TeamBotController', BOT)
00475	    {
00476	        if( ( Bot.TeamID == TeamID ) && ( BOT != self ) )
00477	        {
00478	            MyTeam.Length = MyTeam.Length+1;
00479	            MyTeam[ MyTeam.Length-1 ] = BOT;
00480	        }
00481	    }
00482	
00483	    FindTeamRole();
00484	
00485	    if( DBugBot )
00486	    {
00487	        Log("");
00488	        Log("[ BOT"@ID@"][ Team"@TeamID@"][ Level"@int(Skill)@"] : PickUpList Construction");
00489	        log("    > MedKit="$MedKitList.Length);
00490	        log("    > Weapon="$WeaponList.Length);
00491	        log("    > Armor="$ArmorList.Length);
00492	        log("    > SnipePoint="$SnipeSpotList.Length);
00493	        Log("    > Other Team Bot :"@MyTeam.Length );
00494	
00495	        if( MyTeam.Length != 0 )
00496	        {
00497	            for( Loop = 0 ; Loop < MyTeam.Length ; Loop++ )
00498	                 log("     "@Loop@":"@MyTeam[ Loop ]);
00499	
00500	            Leader = MyTeam[ 0 ].Pawn;
00501	        }
00502	
00503	        Log("    > SafePoint="$HideSpotList.Length);
00504	        If( TeamRole == 0 )
00505	            Log("    > Role("$TeamRole$")=Attack");
00506	        else If( TeamRole == 1 )
00507	            Log("    > Role("$TeamRole$")=Defense");
00508	        else
00509	            Log("    > Role("$TeamRole$")=Support");
00510	        Log("    > GoPoint="$GoPointList.Length);
00511	        Log("    > BackPoint="$BackPointList.Length);
00512	        Log("    > GuardPoint="$GuardPointList.Length);
00513	        Log("    > WaitPoint="$WaitPointList.Length);
00514	        log("    > WatchPoint="$WatchPointList.Length);
00515	    }
00516	
00517	    foreach DynamicActors(class'XIIIMPFlag', TmpFlag)
00518	    {
00519	        if ( PlayerReplicationInfo.Team == TmpFlag.Team )
00520	           MyFlag = TmpFlag;
00521	        else
00522	           EnemyFlag = TmpFlag;
00523	    }
00524	}
00525	
00526	//__________________________________________________________________
00527	
00528	function int GetFlagState(XIIIMPFlag F)
00529	{
00530	    if ( F.bHome )
00531	        return cHome;
00532	    else if ( F.bHeld )
00533	        return cHeld;
00534	    else
00535	        return cDropped;
00536	}
00537	
00538	//__________________________________________________________________
00539	
00540	function FlagPathStorage( actor Target)
00541	{
00542	    local int Loop;
00543	
00544	    if( NavToUpDate != none )
00545	    {
00546	        NavToUpDate.bSpecialCost=false;
00547	        NavToUpDate = none;
00548	    }
00549	
00550	    if (Vsize(Target.location-pawn.location)<400 && ActorReachable(Target))  //FRD in order to test direct and near path
00551	    {
00552	        movetarget=target;
00553	        PathCacheSize = 1;
00554	        PathCache[ 0 ] = target;
00555	        FullPath=true;
00556	        return;
00557	    }
00558	
00559	    if( GetFlagState( XIIIMPFlag(Target) ) == 2 ) // Dropped
00560	    {
00561	        MoveTarget = FindPathToward(Target);
00562	
00563	        if( MoveTarget == none ) // StaticMesh
00564	            MoveTarget = FindPathTo(Target.Location + vect(0,0,70) );
00565	    }
00566	    else
00567	        MoveTarget = ExtendFindPathToward(Target);
00568	
00569	
00570	    PathCacheSize = 0;
00571	
00572	    if( MoveTarget == none )
00573	    {
00574	        PathCacheSize = 0;
00575	        FullPath=false;
00576	    }
00577	    else
00578	    {
00579	        for( Loop=0;Loop<16;Loop++)
00580	        {
00581	            if( RouteCache[ Loop ] == none )
00582	                break;
00583	
00584	//            log(" >"@Loop@":"@RouteCache[ Loop ]);
00585	
00586	            PathCache[ Loop ] = RouteCache[ Loop ];
00587	
00588	            PathCacheSize++;
00589	        }
00590	
00591	        FullPath = ( XIIIMPFlagBase(PathCache[ PathCacheSize-1 ]) != none );
00592	
00593	        if( ! FullPath )
00594	            FullPath = ( XIIIMPFlag(PathCache[ PathCacheSize-1 ]) != none );
00595	    }
00596	
00597	//    log("");
00598	}
00599	
00600	//__________________________________________________________________
00601	
00602	event AddDefaultOrders()
00603	{
00604	    super(BotController).AddDefaultOrders();
00605	
00606	    GoPhase=0;
00607	    BackPhase=0;
00608	
00609	
00610	    switch( TeamRole )
00611	    {
00612	        case cAttack :
00613	        case cSupport :
00614	
00615	             if( GetFlagState( MyFlag ) == cHome )
00616	             {
00617	                 //log("GetFlagState="@GetFlagState( EnemyFlag ));
00618	
00619	                 if( GetFlagState( EnemyFlag ) != cHeld )
00620	                 {
00621	                    if( JustRespawn )
00622	                        AddOrder( 39 , Order_WaitBeforeAttack , "Wait Before Attack",0);
00623	
00624	                    AddOrder( 38 , Order_CaptureTheFlag , "Attack The Flag",0);
00625	                 }
00626	                 else
00627	                 {
00628	                    Leader = EnemyFlag.Holder;
00629	                    AddOrder( 65,Order_ProtectTheHolder,"Protect The Holder",0);
00630	                 }
00631	             }
00632	             else
00633	                AddOrder( 75 , Order_SeekTheFlag , "Retrive My Flag",0);
00634	
00635	             break;
00636	
00637	        case cDefense :
00638	
00639	             if( GetFlagState( MyFlag ) == cHome )
00640	                AddOrder( 50 , Order_ProtectTheFlag , "Protect The Flag",0);
00641	             else
00642	                AddOrder( 75 , Order_SeekTheFlag , "Retrive My Flag",0);
00643	
00644	             break;
00645	    }
00646	}
00647	
00648	//__________________________________________________________________
00649	
00650	event ChangeState()
00651	{
00652	    if( DBugOrder ) LogOrderList();
00653	
00654	    switch( CurrentOrder.TypeId )
00655	    {
00656	        case Order_CaptureTheFlag : GotoState( 'CaptureTheFlag' ); break;
00657	        case Order_ProtectTheFlag : gotoState( 'ProtectTheFlag' ); break;
00658	        case Order_SeekTheFlag : GotoState( 'SeekTheFlag' ); break;
00659	        case Order_BringBackTheFlag : GotoState( 'BringBackTheFlag' ); break;
00660	        case Order_GoToSafePoint : GotoState( 'GoToSafePoint' ); break;
00661	        case Order_WaitToFlagComeBack : GotoState( 'WaitToFlagComeBack' ); break;
00662	        case Order_WaitBeforeAttack : GotoState( 'WaitBeforeAttack' ); break;
00663	        case Order_ProtectTheHolder : GotoState( 'ProtectTheHolder' ); break;
00664	        case Order_Grouping : GotoState( 'Grouping' ); break;
00665	        case Order_UnBump : gotoState( 'UnBump' ); break;
00666	        case Order_Kill : GotoState( 'Kill' ); break;
00667	        case Order_Life : GotoState( 'Life' ); break;
00668	        case Order_Seek : GotoState( 'Seek' ); break;
00669	        case Order_Fear : gotoState( 'Fear' ); break;
00670	        case Order_Weapon : GotoState( 'Weapon' ); break;
00671	        case Order_Armor : GotoState( 'Armor' ); break;
00672	        case Order_SnipeSpot : GotoState( 'SnipeSpot' ); break;
00673	        case Order_SnipeAndKill : GotoState( 'SnipeAndKill' ); break;
00674	        case Order_UnBlock : gotoState( 'UnBlock' ); break;
00675	        case Order_TrakNar : gotoState( 'TrakNar' ); break;
00676	        case Order_GrenadLauncher : gotoState( 'GrenadLauncher' ); break;
00677	   }
00678	}
00679	
00680	//__________________________________________________________________
00681	//__________________________________________________________________
00682	//                            CaptureTheFlag
00683	//__________________________________________________________________
00684	//__________________________________________________________________
00685	
00686	state CaptureTheFlag
00687	{
00688	    event BeginState()
00689	    {
00690	        if( DBugBot )
00691	        {
00692	            Log("");
00693	            Log("[ BOT"@ID@"] : *STATE* ---> CaptureTheFlag");
00694	        }
00695	
00696	        Enemy = none;
00697	        Pawn.ControllerPitch = 0;
00698	
00699	        Pawn.ShouldCrouch( false );
00700	
00701	        NearTheFlag = false;
00702	
00703	        if( ! DontChangeTactikalPoint )
00704	            TacticalPoint = none;
00705	
00706	        DontChangeTactikalPoint = false;
00707	
00708	        LastTestTime = Level.TimeSeconds;
00709	    }
00710	
00711	    //--------------------------------------------------------------
00712	
00713	    event EndState()
00714	    {
00715	        NearTheFlag = false;
00716	        WaitBeforeFire = false;
00717	
00718	        if( SeekAndFire )
00719	        {
00720	            bFire=0;
00721	            Enemy = none;
00722	            if (pawn!=none) Pawn.ControllerPitch = 0;
00723	            SeekAndFire=false;
00724	            SetTimer(0.0,false);
00725	            SetTimer2(0.0,false);
00726	        }
00727	    }
00728	
00729	    //--------------------------------------------------------------
00730	
00731	    function GetRandomGoPoint()
00732	    {
00733	        local int Loop;
00734	        local Array<NavigationPoint> TmpGoPoint;
00735	
00736	        if( DBugBot )
00737	        {
00738	            log("");
00739	            log("[ BOT"@ID@"] : Get Random TacticalPoint");
00740	            log(" > Last:"@LastGoPointUsed);
00741	        }
00742	
00743	        for( Loop =0 ; Loop<GoPointList.Length ; Loop++ )
00744	        {
00745	
00746	            if( GoPointList[Loop] != LastGoPointUsed )
00747	            {
00748	                TmpGoPoint.Length = TmpGoPoint.Length+1;
00749	                TmpGoPoint[ TmpGoPoint.Length-1 ] = GoPointList[ Loop ];
00750	            }
00751	            else if ( Rand( 100 ) < 25 + Skill*25 )
00752	            {
00753	                TmpGoPoint.Length = TmpGoPoint.Length+1;
00754	                TmpGoPoint[ TmpGoPoint.Length-1 ] = GoPointList[ Loop ];
00755	
00756	                if( DBugBot ) log("[ BOT"@ID@"] : Accept the last TacticalPoint");
00757	            }
00758	        }
00759	
00760	        TacticalPoint = TmpGoPoint[Rand( TmpGoPoint.Length )];
00761	        LastGoPointUsed = TacticalPoint;
00762	
00763	        if( DBugBot )
00764	        {
00765	            log(" > New:"@TacticalPoint);
00766	            log("");
00767	        }
00768	    }
00769	
00770	    //--------------------------------------------------------------
00771	
00772	    function int GetLifePriority()
00773	    {
00774	        if( VSize( EnemyFlag.Location - Pawn.Location ) < 1500 )
00775	            return 1;
00776	        else
00777	            return global.GetLifePriority();
00778	    }
00779	
00780	    //--------------------------------------------------------------
00781	
00782	    function float DistToTheEnemyFlag()
00783	    {
00784	        local int Loop;
00785	        local float TmpDist;
00786	
00787	        if( ! FullPath )
00788	             return 10000;
00789	
00790	        if( Level.TimeSeconds - LastTestTime < 0.5 )
00791	             return 10001;
00792	
00793	        //log("DistToTheEnemyFlag ..."@Level.TimeSeconds - LastTestTime);
00794	
00795	        LastTestTime = Level.TimeSeconds;
00796	
00797	        TmpDist = VSize( Pawn.Location - PathCache[ PathIndex ].Location );
00798	
00799	        for( Loop = PathIndex; Loop < PathCacheSize-1 ; Loop ++ )
00800	        {
00801	            TmpDist += VSize( PathCache[ Loop ].Location - PathCache[ Loop+1 ].Location );
00802	        }
00803	
00804	        return TmpDist;
00805	
00806	    }
00807	
00808	    //--------------------------------------------------------------
00809	
00810	    event EnemyNotVisible()
00811	    {
00812	        if( SeekAndFire )
00813	        {
00814	            bFire=0;
00815	            Enemy = none;
00816	            Pawn.ControllerPitch = 0;
00817	            SeekAndFire=false;
00818	            SetTimer(0.0,false);
00819	            SetTimer2(0.0,false);
00820	            Pawn.Weapon.ForceReload();
00821	        }
00822	    }
00823	
00824	    //--------------------------------------------------------------
00825	
00826	    event SeePlayer( Pawn Seen )
00827	    {
00828	        local float TmpDist;
00829	
00830	        if( Enemy != none )
00831	        {
00832	            if( ( WaitBeforeFire ) && ( Seen == Enemy ) )
00833	                WaitBeforeFire = false;
00834	            else
00835	                return;
00836	        }
00837	
00838	        if( ! IsEnemy( Seen ) )
00839	            return;
00840	
00841	        if( ! NearTheFlag )
00842	        {
00843	            TmpDist = DistToTheEnemyFlag();
00844	
00845	            if( TmpDist < 2000 )
00846	                NearTheFlag = true;
00847	        }
00848	
00849	        if( NearTheFlag )
00850	        {
00851	            if( VSize( Seen.Location - Pawn.Location ) > 300 )
00852	            {
00853	                if( ! SeekAndFire )
00854	                {
00855	                    Enemy = Seen;
00856	                    SeekAndFire=true;
00857	                    SetTimer( (4-Skill)*0.2+FRand()/2 ,False );
00858	                }
00859	            }
00860	            else if( ! FindOrder( Order_Kill ) )
00861	            {
00862	                Enemy = Seen;
00863	                DontChangeTactikalPoint=true;
00864	                AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
00865	            }
00866	        }
00867	        else if( ! FindOrder( Order_Kill ) )
00868	        {
00869	            Enemy = Seen;
00870	            DontChangeTactikalPoint=true;
00871	            AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
00872	        }
00873	    }
00874	
00875	    //--------------------------------------------------------------
00876	
00877	    function SomeoneWantKillMe( Pawn Agressor )
00878	    {
00879	        if( ! PathErrorToAllLife )
00880	        {
00881	            if( FindOrder( Order_Life ) )
00882	                ModifyOrder( Order_Life, GetLifePriority() );
00883	            else
00884	                AddOrder(GetLifePriority(),Order_Life,"Life",0);
00885	        }
00886	
00887	        WaitBeforeFire = true;
00888	
00889	        SeePlayer( Agressor );
00890	    }
00891	
00892	    //--------------------------------------------------------------
00893	
00894	    function bool SkipTacticalPoint()
00895	    {
00896	        local float TmpDist;
00897	
00898	        if( GetFlagState( EnemyFlag ) == cDropped )
00899	        {
00900	            TmpDist = VSize( EnemyFlag.Location - Pawn.Location );
00901	
00902	            if( TmpDist < 2000 )
00903	                return true;
00904	            else
00905	                return false;
00906	        }
00907	    }
00908	
00909	    //--------------------------------------------------------------
00910	
00911	begin:
00912	
00913	    while( Pawn.Physics == PHYS_Falling )
00914	        sleep( 0.1 );
00915	
00916	    if( SkipTacticalPoint() )
00917	        GoPhase = 1;
00918	
00919	    while( true )
00920	    {
00921	        if( GoPhase == 0 )
00922	        {
00923	            if( TacticalPoint == none )
00924	                GetRandomGoPoint();
00925	
00926	            NavPathStorage( TacticalPoint );
00927	        }
00928	        else
00929	            FlagPathStorage( EnemyFlag );
00930	
00931	        if( MoveTarget == none )
00932	        {
00933	            Sleep( 0.5 );
00934	            break;
00935	        }
00936	
00937	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
00938	        {
00939	            MoveTarget = PathCache[ PathIndex ];
00940	            Focus=MoveTarget;
00941	            Pawn.ShouldCrouch( false );
00942	
00943	            if( ! SeekAndFire )
00944	                MoveToward( MoveTarget, Focus , MoveSpeed );
00945	            else
00946	                MoveToward( MoveTarget, Enemy , MoveSpeed );
00947	        }
00948	
00949	        if( FullPath )
00950	        {
00951	            if ( GoPhase == 1 )
00952	                break;
00953	            else
00954	                GoPhase++;
00955	        }
00956	    }
00957	
00958	    RemoveOrder( Order_CaptureTheFlag );
00959	}
00960	
00961	//__________________________________________________________________
00962	//__________________________________________________________________
00963	//                            BringBackTheFlag
00964	//__________________________________________________________________
00965	//__________________________________________________________________
00966	
00967	state BringBackTheFlag
00968	{
00969	    event BeginState()
00970	    {
00971	        if( DBugBot )
00972	        {
00973	            Log("");
00974	            Log("[ BOT"@ID@"] : *STATE* ---> BringBackTheFlag");
00975	        }
00976	
00977	        Enemy = none;
00978	        Pawn.ControllerPitch = 0;
00979	
00980	        Pawn.ShouldCrouch( false );
00981	
00982	        NearTheFlag = false;
00983	
00984	        if( ! DontChangeTactikalPoint )
00985	            TacticalPoint = none;
00986	
00987	        DontChangeTactikalPoint = false;
00988	    }
00989	
00990	    //--------------------------------------------------------------
00991	
00992	    event EndState()
00993	    {
00994	        SetTimer3(0.0,false);
00995	        NearTheFlag = false;
00996	        WaitBeforeFire = false;
00997	
00998	        if( SeekAndFire )
00999	        {
01000	            bFire=0;
01001	            Enemy = none;
01002	            if (pawn!=none) Pawn.ControllerPitch = 0;
01003	            SeekAndFire=false;
01004	            SetTimer(0.0,false);
01005	            SetTimer2(0.0,false);
01006	        }
01007	    }
01008	
01009	    //--------------------------------------------------------------
01010	
01011	    event EnemyNotVisible()
01012	    {
01013	        if( SeekAndFire )
01014	        {
01015	            bFire=0;
01016	            Enemy = none;
01017	            Pawn.ControllerPitch = 0;
01018	            SeekAndFire=false;
01019	            SetTimer(0.0,false);
01020	            SetTimer2(0.0,false);
01021	            Pawn.Weapon.ForceReload();
01022	        }
01023	    }
01024	
01025	    //--------------------------------------------------------------
01026	
01027	    function float DistToMyFlag()
01028	    {
01029	        local int Loop;
01030	        local float TmpDist;
01031	
01032	        if( ! FullPath )
01033	             return 10000;
01034	
01035	        TmpDist = VSize( Pawn.Location - PathCache[ PathIndex ].Location );
01036	
01037	        for( Loop = PathIndex; Loop < PathCacheSize-1 ; Loop ++ )
01038	        {
01039	            TmpDist += VSize( PathCache[ Loop ].Location - PathCache[ Loop+1 ].Location );
01040	        }
01041	
01042	        return TmpDist;
01043	
01044	    }
01045	
01046	    //--------------------------------------------------------------
01047	
01048	    event SeePlayer( Pawn Seen )
01049	    {
01050	        local float DistToTheEnemy;
01051	
01052	        if( Enemy != none )
01053	            return;
01054	
01055	        if( ! IsEnemy( Seen ) )
01056	            return;
01057	
01058	        DistToTheEnemy = VSize( Seen.Location - Pawn.Location );
01059	
01060	        if( ( DistToTheEnemy > 300 ) && ( DistToTheEnemy < 700 ) )
01061	        {
01062	            if( ! SeekAndFire )
01063	            {
01064	                Enemy = Seen;
01065	                SeekAndFire=true;
01066	                SetTimer( (4-Skill)*0.2+FRand()/2 ,False );
01067	            }
01068	        }
01069	        else if( DistToTheEnemy < 300 )
01070	        {
01071	            Enemy = Seen;
01072	            DontChangeTactikalPoint=true;
01073	            AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01074	        }
01075	    }
01076	
01077	    //--------------------------------------------------------------
01078	
01079	    function SomeoneWantKillMe( Pawn Agressor )
01080	    {
01081	        if( ! PathErrorToAllLife )
01082	        {
01083	            if( FindOrder( Order_Life ) )
01084	                ModifyOrder( Order_Life, GetLifePriority() );
01085	            else
01086	                AddOrder(GetLifePriority(),Order_Life,"Life",0);
01087	        }
01088	
01089	        SeePlayer( Agressor );
01090	    }
01091	
01092	    //--------------------------------------------------------------
01093	
01094	    function int GetLifePriority()
01095	    {
01096	        if( BackPhase == 0 )
01097	            return 1;
01098	
01099	        if( VSize( MyFlag.Location - Pawn.Location ) < 1500 )
01100	            return 1;
01101	
01102	        return global.GetLifePriority();
01103	    }
01104	
01105	    //--------------------------------------------------------------
01106	
01107	    function GetRandomBackPoint()
01108	    {
01109	        local int Loop;
01110	        local Array<NavigationPoint> TmpGoPoint;
01111	
01112	        if( DBugBot )
01113	        {
01114	            log("");
01115	            log("[ BOT"@ID@"] : Get Random TacticalPoint");
01116	            log(" > Last:"@LastBackPointUsed);
01117	        }
01118	
01119	        for( Loop =0 ; Loop<BackPointList.Length ; Loop++ )
01120	        {
01121	            if( BackPointList[Loop] != LastBackPointUsed )
01122	            {
01123	                TmpGoPoint.Length = TmpGoPoint.Length+1;
01124	                TmpGoPoint[ TmpGoPoint.Length-1 ] = BackPointList[ Loop ];
01125	            }
01126	            else if ( Rand( 100 ) < 25 + Skill*25 )
01127	            {
01128	                TmpGoPoint.Length = TmpGoPoint.Length+1;
01129	                TmpGoPoint[ TmpGoPoint.Length-1 ] = BackPointList[ Loop ];
01130	
01131	                if( DBugBot ) log("[ BOT"@ID@"] : Accept the last TacticalPoint");
01132	            }
01133	        }
01134	
01135	        TacticalPoint = TmpGoPoint[Rand( TmpGoPoint.Length )];
01136	        LastBackPointUsed = TacticalPoint;
01137	
01138	        if( DBugBot )
01139	        {
01140	            log(" > New:"@TacticalPoint);
01141	            log("");
01142	        }
01143	    }
01144	
01145	    //--------------------------------------------------------------
01146	
01147	    function bool StopOrder()
01148	    {
01149	        if( GetFlagState( MyFlag ) != cHome )
01150	            return true;
01151	        else
01152	            return false;
01153	    }
01154	
01155	    //--------------------------------------------------------------
01156	
01157	    event Timer3()
01158	    {
01159	        log("");
01160	        log("--------------------------------------------");
01161	        log("[ BOT"@ID@"] : !!! ANTIBUG BringBackTheFlag !!!");
01162	        LogOrderList();
01163	        log("--------------------------------------------");
01164	        log("");
01165	
01166	        LastDefaultOrderTime=0;
01167	        ClearAllOrders();
01168	    }
01169	
01170	    //--------------------------------------------------------------
01171	
01172	    function bool SkipTacticalPoint()
01173	    {
01174	        local float TmpDist;
01175	
01176	        if( GetFlagState( MyFlag ) == cHome )
01177	        {
01178	            TmpDist = VSize( MyFlag.HomeBase.Location - Pawn.Location );
01179	
01180	            if( TmpDist < 2000 )
01181	                return true;
01182	            else
01183	                return false;
01184	        }
01185	    }
01186	
01187	    //--------------------------------------------------------------
01188	
01189	begin:
01190	
01191	    while( Pawn.Physics == PHYS_Falling )
01192	        sleep( 0.1 );
01193	
01194	    if( SkipTacticalPoint() )
01195	        BackPhase = 1;
01196	
01197	
01198	    while( true )
01199	    {
01200	        if( BackPhase == 0 )
01201	        {
01202	            if( TacticalPoint == none )
01203	                GetRandomBackPoint();
01204	
01205	            NavPathStorage( TacticalPoint );
01206	        }
01207	        else
01208	            NavPathStorage( MyFlag.HomeBase );
01209	
01210	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01211	        {
01212	            if( StopOrder() )
01213	            {
01214	                AddOrder( 75 , Order_GoToSafePoint , "Go To Safe Point",0);
01215	                RemoveOrder( Order_BringBackTheFlag );
01216	            }
01217	
01218	            Pawn.ShouldCrouch( false );
01219	            MoveTarget = PathCache[ PathIndex ];
01220	            Focus=MoveTarget;
01221	
01222	            if( ! SeekAndFire )
01223	                MoveToward( MoveTarget, Focus , MoveSpeed );
01224	            else
01225	                MoveToward( MoveTarget, Enemy , MoveSpeed );
01226	        }
01227	
01228	        if( FullPath )
01229	        {
01230	            if ( BackPhase == 1 )
01231	                break;
01232	            else
01233	                BackPhase++;
01234	        }
01235	    }
01236	
01237	    SetTimer3(2.0,false);
01238	    //sleep( 1.0 );
01239	    JustRespawn =true;
01240	    RemoveOrder( Order_BringBackTheFlag );
01241	}
01242	
01243	
01244	//__________________________________________________________________
01245	//__________________________________________________________________
01246	//                            GoToSafePoint
01247	//__________________________________________________________________
01248	//__________________________________________________________________
01249	
01250	state GoToSafePoint
01251	{
01252	    event BeginState()
01253	    {
01254	        if( DBugBot )
01255	        {
01256	            Log("");
01257	            Log("[ BOT"@ID@"] : *STATE* ---> GoToSafePoint");
01258	        }
01259	
01260	        Enemy = none;
01261	        Pawn.ControllerPitch = 0;
01262	
01263	        Pawn.ShouldCrouch( false );
01264	
01265	        NearTheFlag = false;
01266	
01267	        if( ! DontChangeTactikalPoint )
01268	            TacticalPoint = none;
01269	
01270	        DontChangeTactikalPoint = false;
01271	    }
01272	
01273	    //--------------------------------------------------------------
01274	
01275	    event EndState()
01276	    {
01277	        NearTheFlag = false;
01278	
01279	        if( SeekAndFire )
01280	        {
01281	            bFire=0;
01282	            Enemy = none;
01283	            if (pawn!=none) Pawn.ControllerPitch = 0;
01284	            SeekAndFire=false;
01285	            SetTimer(0.0,false);
01286	            SetTimer2(0.0,false);
01287	        }
01288	    }
01289	
01290	    //--------------------------------------------------------------
01291	
01292	    event EnemyNotVisible()
01293	    {
01294	        if( SeekAndFire )
01295	        {
01296	            bFire=0;
01297	            Enemy = none;
01298	            Pawn.ControllerPitch = 0;
01299	            SeekAndFire=false;
01300	            SetTimer(0.0,false);
01301	            SetTimer2(0.0,false);
01302	            Pawn.Weapon.ForceReload();
01303	        }
01304	    }
01305	
01306	    //--------------------------------------------------------------
01307	
01308	    function float DistToMyFlag()
01309	    {
01310	        local int Loop;
01311	        local float TmpDist;
01312	
01313	        if( ! FullPath )
01314	             return 10000;
01315	
01316	        TmpDist = VSize( Pawn.Location - PathCache[ PathIndex ].Location );
01317	
01318	        for( Loop = PathIndex; Loop < PathCacheSize-1 ; Loop ++ )
01319	        {
01320	            TmpDist += VSize( PathCache[ Loop ].Location - PathCache[ Loop+1 ].Location );
01321	        }
01322	
01323	        return TmpDist;
01324	
01325	    }
01326	
01327	    //--------------------------------------------------------------
01328	
01329	    event SeePlayer( Pawn Seen )
01330	    {
01331	        local float DistToTheEnemy;
01332	
01333	        if( Enemy != none )
01334	            return;
01335	
01336	        if( ! IsEnemy( Seen ) )
01337	            return;
01338	
01339	        DistToTheEnemy = VSize( Seen.Location - Pawn.Location );
01340	
01341	        if( ( DistToTheEnemy > 300 ) && ( DistToTheEnemy < 700 ) )
01342	        {
01343	            if( ! SeekAndFire )
01344	            {
01345	                Enemy = Seen;
01346	                SeekAndFire=true;
01347	                SetTimer( (4-Skill)*0.2+FRand()/2 ,False );
01348	            }
01349	        }
01350	        else if( DistToTheEnemy < 300 )
01351	        {
01352	            Enemy = Seen;
01353	            DontChangeTactikalPoint=true;
01354	            AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01355	        }
01356	    }
01357	
01358	    //--------------------------------------------------------------
01359	
01360	    function SomeoneWantKillMe( Pawn Agressor )
01361	    {
01362	        if( ! PathErrorToAllLife )
01363	        {
01364	            if( FindOrder( Order_Life ) )
01365	                ModifyOrder( Order_Life, GetLifePriority() );
01366	            else
01367	                AddOrder(GetLifePriority(),Order_Life,"Life",0);
01368	        }
01369	
01370	        SeePlayer( Agressor );
01371	    }
01372	
01373	    //--------------------------------------------------------------
01374	
01375	    function int GetLifePriority()
01376	    {
01377	        if( BackPhase == 0 )
01378	            return 1;
01379	
01380	        return global.GetLifePriority();
01381	    }
01382	
01383	    //--------------------------------------------------------------
01384	
01385	    function GetRandomSafePoint()
01386	    {
01387	        HidePoint = HideSpotList[Rand( HideSpotList.Length)];
01388	    }
01389	
01390	    //--------------------------------------------------------------
01391	
01392	    function GetRandomBackPoint()
01393	    {
01394	        local int Loop;
01395	        local Array<NavigationPoint> TmpGoPoint;
01396	
01397	        if( DBugBot )
01398	        {
01399	            log("");
01400	            log("[ BOT"@ID@"] : Get Random TacticalPoint");
01401	            log(" > Last:"@LastBackPointUsed);
01402	        }
01403	
01404	        for( Loop =0 ; Loop<BackPointList.Length ; Loop++ )
01405	        {
01406	            if( BackPointList[Loop] != LastBackPointUsed )
01407	            {
01408	                TmpGoPoint.Length = TmpGoPoint.Length+1;
01409	                TmpGoPoint[ TmpGoPoint.Length-1 ] = BackPointList[ Loop ];
01410	            }
01411	        }
01412	
01413	        TacticalPoint = TmpGoPoint[Rand( TmpGoPoint.Length )];
01414	        LastBackPointUsed = TacticalPoint;
01415	
01416	        if( DBugBot )
01417	        {
01418	            log(" > New:"@TacticalPoint);
01419	            log("");
01420	        }
01421	    }
01422	
01423	    //--------------------------------------------------------------
01424	
01425	    function bool StopOrder()
01426	    {
01427	        if( GetFlagState( MyFlag ) == cHome )
01428	            return true;
01429	        else
01430	            return false;
01431	    }
01432	
01433	    //--------------------------------------------------------------
01434	
01435	begin:
01436	
01437	    if( Pawn.Physics == PHYS_Falling )
01438	    {
01439	        while( true )
01440	        {
01441	            sleep( 0.1 );
01442	
01443	            if ( Pawn.Physics != PHYS_Falling )
01444	               break;
01445	        }
01446	    }
01447	
01448	    while( true )
01449	    {
01450	        if( BackPhase == 0 )
01451	        {
01452	            if( TacticalPoint == none )
01453	                GetRandomBackPoint();
01454	
01455	            NavPathStorage( TacticalPoint );
01456	        }
01457	        else
01458	        {
01459	            GetRandomSafePoint();
01460	            NavPathStorage( HidePoint );
01461	        }
01462	
01463	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01464	        {
01465	            if( StopOrder() )
01466	            {
01467	                AddOrder( 75 , Order_BringBackTheFlag , "BringBackTheFlag",0);
01468	                RemoveOrder( Order_GoToSafePoint );
01469	            }
01470	
01471	            Pawn.ShouldCrouch( false );
01472	            MoveTarget = PathCache[ PathIndex ];
01473	            Focus=MoveTarget;
01474	
01475	            if( ! SeekAndFire )
01476	                MoveToward( MoveTarget, Focus , MoveSpeed );
01477	            else
01478	                MoveToward( MoveTarget, Enemy , MoveSpeed );
01479	        }
01480	
01481	        if( PathIndex != PathCacheSize )
01482	            break;
01483	
01484	        if( FullPath )
01485	        {
01486	            if ( BackPhase == 1 )
01487	                break;
01488	            else
01489	                BackPhase++;
01490	        }
01491	    }
01492	
01493	    AddOrder( 75 , Order_WaitToFlagComeBack , "BringBackTheFlag",0);
01494	    RemoveOrder( Order_GoToSafePoint );
01495	}
01496	
01497	//__________________________________________________________________
01498	//__________________________________________________________________
01499	//                            WaitToFlagComeBack
01500	//__________________________________________________________________
01501	//__________________________________________________________________
01502	
01503	state WaitToFlagComeBack
01504	{
01505	    event BeginState()
01506	    {
01507	        if( DBugBot )
01508	        {
01509	            Log("");
01510	            Log("[ BOT"@ID@"] : *STATE* ---> WaitToFlagComeBack");
01511	        }
01512	
01513	        Pawn.velocity=vect(0,0,0);
01514	        Pawn.acceleration=vect(0,0,0);
01515	        Focus = none;
01516	        FocalPoint = vector(HidePoint.rotation)*10000+Pawn.Location;
01517	
01518	        Enemy = none;
01519	        Pawn.ShouldCrouch( true );
01520	
01521	        HideTime = Level.TimeSeconds;
01522	        MaxHideTime = 20 + Rand( 20 );
01523	    }
01524	
01525	    //--------------------------------------------------------------
01526	
01527	    event EndState()
01528	    {
01529	        if (pawn!=none) Pawn.SpineYawControl(false,3000, 1.2);
01530	    }
01531	
01532	    //--------------------------------------------------------------
01533	
01534	    event SeePlayer( Pawn Seen )
01535	    {
01536	        if( VSize( Seen.Location - Pawn.Location ) < 2000 )
01537	            SomeoneWantKillMe( Seen );
01538	    }
01539	
01540	    //--------------------------------------------------------------
01541	
01542	    function SomeoneWantKillMe( Pawn Agressor )
01543	    {
01544	        if( ! PathErrorToAllLife )
01545	        {
01546	            if( FindOrder( Order_Life ) )
01547	                ModifyOrder( Order_Life, GetLifePriority() );
01548	            else
01549	                AddOrder(GetLifePriority(),Order_Life,"Life",0);
01550	        }
01551	
01552	        if( ! IsEnemy( Agressor ) )
01553	            return;
01554	
01555	        if( !FindOrder( Order_Kill ) )
01556	        {
01557	            Enemy = Agressor;
01558	
01559	            if( ! FindOrder( Order_Kill ) )
01560	            {
01561	                AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01562	                AddOrder( 75 , Order_GoToSafePoint , "Go To Safe Point",0);
01563	                RemoveOrder( Order_WaitToFlagComeBack );
01564	            }
01565	        }
01566	    }
01567	
01568	    //--------------------------------------------------------------
01569	
01570	begin:
01571	
01572	    Pawn.SpineYawControl(true,3000, 1.2);
01573	
01574	    while( true )
01575	    {
01576	        if( GetFlagState( MyFlag ) == cHome )
01577	        {
01578	            Sleep( FRand() );
01579	            BackPhase = 1;
01580	            AddOrder( 75 , Order_BringBackTheFlag , "BringBackTheFlag",0);
01581	            RemoveOrder( Order_WaitToFlagComeBack );
01582	        }
01583	        else
01584	            Sleep( 1.0 );
01585	
01586	        if( Level.TimeSeconds - HideTime > MaxHideTime )
01587	        {
01588	            AddOrder( 75 , Order_GoToSafePoint , "Go To Safe Point",0);
01589	            RemoveOrder( Order_WaitToFlagComeBack );
01590	        }
01591	    }
01592	}
01593	
01594	
01595	//__________________________________________________________________
01596	//__________________________________________________________________
01597	//                            ProtectTheFlag
01598	//__________________________________________________________________
01599	//__________________________________________________________________
01600	
01601	state ProtectTheFlag
01602	{
01603	    event BeginState()
01604	    {
01605	        if( DBugBot )
01606	        {
01607	            Log("");
01608	            Log("[ BOT"@ID@"] : *STATE* ---> ProtectTheFlag");
01609	        }
01610	
01611	        Pawn.ShouldCrouch( false );
01612	
01613	        Enemy = none;
01614	        Pawn.ControllerPitch = 0;
01615	
01616	        MaxProtectTime = 20 + Rand( 20 );
01617	        ProtectTime = Level.TimeSeconds;
01618	
01619	        SetTimer3( 1.0 , true );
01620	    }
01621	
01622	    //--------------------------------------------------------------
01623	
01624	    event EndState()
01625	    {
01626	        SetTimer3( 0.0 , false );
01627	        GuardPathNode(TacticalPoint).Closed = false;
01628			if (pawn!=none)
01629			{
01630	        Pawn.SpineYawControl(false,3000, 1.2);
01631	        Pawn.ShouldCrouch( false );
01632			}
01633	    }
01634	
01635	    //--------------------------------------------------------------
01636	
01637	    function GetRandomGuardPoint()
01638	    {
01639	        local Array<NavigationPoint> TempList;
01640	        local int Loop;
01641	        local NavigationPoint TempPoint;
01642	
01643	        for( Loop=0;Loop<GuardPointList.Length;Loop++)
01644	        {
01645	            TempPoint = GuardPointList[ Loop ];
01646	
01647	            if( ! GuardPathNode(TempPoint).Closed )
01648	            {
01649	                TempList.Length = TempList.Length+1;
01650	                TempList[ TempList.Length-1 ] = TempPoint;
01651	            }
01652	        }
01653	
01654	        TacticalPoint = TempList[Rand( TempList.Length)];
01655	    }
01656	
01657	    //--------------------------------------------------------------
01658	
01659	    function bool StopOrder()
01660	    {
01661	        if( GetFlagState( MyFlag ) != cHome )
01662	            return true;
01663	        else
01664	            return false;
01665	    }
01666	
01667	    //--------------------------------------------------------------
01668	
01669	    event Timer3()
01670	    {
01671	        local float TmpDist;
01672	
01673	        if( GetFlagState( EnemyFlag ) == cDropped )
01674	        {
01675	            TmpDist = VSize( EnemyFlag.Location - Pawn.Location );
01676	
01677	            //log("----"@TmpDist@"----");
01678	
01679	            if( TmpDist < 2000 )
01680	            {
01681	                AddOrder( 79 , Order_CaptureTheFlag , "Attack The Flag",0);
01682	            }
01683	        }
01684	    }
01685	
01686	    //--------------------------------------------------------------
01687	
01688	Begin :
01689	
01690	    if( Pawn.Physics == PHYS_Falling )
01691	    {
01692	        while( true )
01693	        {
01694	            sleep( 0.1 );
01695	
01696	            if ( Pawn.Physics != PHYS_Falling )
01697	               break;
01698	        }
01699	    }
01700	
01701	    GetRandomGuardPoint();
01702	
01703	    Pawn.ShouldCrouch( false );
01704	
01705	    while( true )
01706	    {
01707	        NavPathStorage( TacticalPoint );
01708	
01709	        if( MoveTarget == none )
01710	        {
01711	            Sleep( 0.5 );
01712	            break;
01713	        }
01714	
01715	        GuardPathNode(TacticalPoint).Closed = true;
01716	
01717	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01718	        {
01719	            if( StopOrder() )
01720	            {
01721	                AddOrder( 75 , Order_SeekTheFlag , "Retrive My Flag",0);
01722	                RemoveOrder(Order_ProtectTheFlag);
01723	            }
01724	
01725	            Pawn.ShouldCrouch( false );
01726	
01727	            MoveTarget = PathCache[ PathIndex ];
01728	            Focus=MoveTarget;
01729	
01730	            MoveToward( MoveTarget, Focus , MoveSpeed );
01731	        }
01732	
01733	        if( FullPath )
01734	            break;
01735	    }
01736	
01737	    Focus = none;
01738	    FocalPoint = vector(TacticalPoint.rotation)*10000+Pawn.Location;
01739	    Pawn.SpineYawControl(true,3000, 1.2);
01740	
01741	    if( Rand( 100 ) < 50 )
01742	        Pawn.ShouldCrouch( true );
01743	    else
01744	        Pawn.ShouldCrouch( false );
01745	
01746	    while( true )
01747	    {
01748	        if( GetFlagState( MyFlag ) == cHome )
01749	            Sleep( 1.0 );
01750	        else
01751	        {
01752	            AddOrder( 75 , Order_SeekTheFlag , "Retrive My Flag",0);
01753	            RemoveOrder(Order_ProtectTheFlag);
01754	        }
01755	
01756	        if( Level.TimeSeconds - ProtectTime > MaxProtectTime )
01757	        {
01758	            if( Rand( 100 ) < 30 )
01759	            {
01760	                RemoveOrder(Order_ProtectTheFlag);
01761	            }
01762	            else
01763	            {
01764	                ProtectTime = Level.TimeSeconds;
01765	                GuardPathNode(TacticalPoint).Closed = false;
01766	                Pawn.ShouldCrouch( false );
01767	                Goto('begin');
01768	             }
01769	        }
01770	    }
01771	}
01772	
01773	//__________________________________________________________________
01774	//__________________________________________________________________
01775	//                            SeekTheFlag
01776	//__________________________________________________________________
01777	//__________________________________________________________________
01778	
01779	state SeekTheFlag
01780	{
01781	    event BeginState()
01782	    {
01783	        if( DBugBot )
01784	        {
01785	            Log("");
01786	            Log("[ BOT"@ID@"] : *STATE* ---> SeekTheFlag");
01787	        }
01788	
01789	        Enemy = MyFlag.Holder;
01790	        Pawn.ControllerPitch = 0;
01791	
01792	        Pawn.ShouldCrouch( false );
01793	
01794	        LastSeeTime = Level.TimeSeconds;
01795	    }
01796	
01797	    //--------------------------------------------------------------
01798	
01799	    event EndState()
01800	    {
01801	        bFire=0;
01802	        SetTimer(0.0,false);
01803	        SetTimer2(0.0,false);
01804	        SeekAndFire=false;
01805	    }
01806	
01807	    //--------------------------------------------------------------
01808	
01809	    event EnemyNotVisible()
01810	    {
01811	        if( SeekAndFire )
01812	        {
01813	            bFire=0;
01814	            SeekAndFire=false;
01815	            SetTimer(0.0,false);
01816	            SetTimer2(0.0,false);
01817	            Pawn.Weapon.ForceReload();
01818	        }
01819	    }
01820	
01821	    //--------------------------------------------------------------
01822	
01823	    function bool StopOrder()
01824	    {
01825	        if( ( ( TeamRole == cDefense ) && ( Level.TimeSeconds - LastSeeTime > 20 ) ) && ( GetFlagState( EnemyFlag ) != cHeld ) )
01826	        {
01827	            if( DBugBot )
01828	            {
01829	                Log("");
01830	                Log("[ BOT"@ID@"] : ABORD SeekTheFlag Time without seeing the Holder ="@int(Level.TimeSeconds - LastSeeTime)@"s");
01831	            }
01832	
01833	            return true;
01834	        }
01835	
01836	        if( GetFlagState( MyFlag ) == cHome )
01837	            return true;
01838	        else
01839	            return false;
01840	    }
01841	
01842	    //--------------------------------------------------------------
01843	
01844	    event SeePlayer( Pawn Seen )
01845	    {
01846	        if( ! IsEnemy( Seen ) )
01847	            return;
01848	
01849	        if( Seen == Enemy )
01850	        {
01851	            LastSeeTime = Level.TimeSeconds;
01852	
01853	            if( IsShootable( Seen ) )
01854	            {
01855	                if( VSize( Seen.Location - Pawn.Location ) > 200 )
01856	                {
01857	                    if( ! SeekAndFire )
01858	                    {
01859	                        SeekAndFire=true;
01860	                        SetTimer( (4-Skill)*0.2+FRand()/2 ,False );
01861	                    }
01862	                }
01863	                else if( ! FindOrder( Order_Kill ) )
01864	                    AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01865	            }
01866	        }
01867	        else if( ( VSize( Seen.Location - Pawn.Location ) < 400 ) && ( Rand( 100 ) < 90 - Skill*20 ) )
01868	        {
01869	            if( IsShootable(Seen) )
01870	            {
01871	                Enemy = Seen;
01872	
01873	                if( ! FindOrder( Order_Kill ) )
01874	                    AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
01875	            }
01876	        }
01877	    }
01878	
01879	    //--------------------------------------------------------------
01880	
01881	    function int GetLifePriority()
01882	    {
01883	        if( VSize( MyFlag.Location - Pawn.Location ) < 1500 )
01884	            return 1;
01885	
01886	        return global.GetLifePriority();
01887	    }
01888	
01889	    //--------------------------------------------------------------
01890	
01891	    event bool NotifyBump(Actor Other);
01892	
01893	    //--------------------------------------------------------------
01894	
01895	Begin :
01896	
01897	    Sleep( FRand()/4 );
01898	
01899	    while( true )
01900	    {
01901	        FlagPathStorage( MyFlag );
01902	
01903	        if( MoveTarget == none )
01904	        {
01905	            log("!!! Impossible de rechercher le flag !!!");
01906	            Sleep( 0.5 );
01907	            break;
01908	        }
01909	
01910	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
01911	        {
01912	            if( StopOrder() )
01913	                break;
01914	
01915	            Pawn.ShouldCrouch( false );
01916	            MoveTarget = PathCache[ PathIndex ];
01917	            Focus=MoveTarget;
01918	
01919	            if( ! SeekAndFire )
01920	                MoveToward( MoveTarget, Focus , MoveSpeed*1.1 );
01921	            else
01922	                MoveToward( MoveTarget, Enemy , MoveSpeed*1.1 );
01923	        }
01924	
01925	        if( StopOrder() )
01926	            break;
01927	        else
01928	            goto('begin');
01929	    }
01930	
01931	    RemoveOrder(Order_SeekTheFlag);
01932	}
01933	
01934	//__________________________________________________________________
01935	//__________________________________________________________________
01936	//                            Kill
01937	//__________________________________________________________________
01938	//__________________________________________________________________
01939	
01940	state Kill
01941	{
01942	    event BeginState()
01943	    {
01944	        if( Enemy == none )
01945	            RemoveOrder( Order_Kill );
01946	
01947	        super.BeginState();
01948	    }
01949	
01950	    //--------------------------------------------------------------
01951	
01952	    event EnemyNotVisible()
01953	    {
01954	        if( Pawn.bIsCrouched )
01955	            Pawn.ShouldCrouch( false );
01956	
01957	        bFire=0;
01958	
01959	        if( ( Enemy == MyFlag.Holder ) || ( bFireMove ) )
01960	            AddOrder( 70 ,Order_Seek,"Seek", 0);
01961	        else
01962	            Enemy = none;
01963	
01964	        RemoveOrder( Order_Kill );
01965	    }
01966	
01967	    //--------------------------------------------------------------
01968	
01969	    function int GetLifePriority()
01970	    {
01971	        if( Enemy == MyFlag.Holder )
01972	            return 1;
01973	
01974	        return global.GetLifePriority();
01975	    }
01976	}
01977	
01978	//__________________________________________________________________
01979	//__________________________________________________________________
01980	//                            WaitBeforeAttack
01981	//__________________________________________________________________
01982	//__________________________________________________________________
01983	
01984	state WaitBeforeAttack
01985	{
01986	    event BeginState()
01987	    {
01988	        if( DBugBot )
01989	        {
01990	            Log("");
01991	            Log("[ BOT"@ID@"] : *STATE* ---> WaitBeforeAttack");
01992	        }
01993	
01994	        JustRespawn=false;
01995	        ReadyToAttack=false;
01996	
01997	        Enemy = none;
01998	        Pawn.ControllerPitch = 0;
01999	
02000	        MaxProtectTime = 40;
02001	        ProtectTime = Level.TimeSeconds;
02002	    }
02003	
02004	    //--------------------------------------------------------------
02005	
02006	    event EndState()
02007	    {
02008	        GuardPathNode(TacticalPoint).Closed = false;
02009			if (pawn!=none)
02010			{
02011	        Pawn.SpineYawControl(false,3000, 1.2);
02012	        Pawn.ShouldCrouch( false );
02013			}
02014	    }
02015	
02016	    //--------------------------------------------------------------
02017	
02018	    function GetRandomWaitPoint()
02019	    {
02020	        local Array<NavigationPoint> TempList;
02021	        local int Loop;
02022	        local NavigationPoint TempPoint;
02023	
02024	        for( Loop=0;Loop<WaitPointList.Length;Loop++)
02025	        {
02026	            TempPoint = WaitPointList[ Loop ];
02027	
02028	            if( ! GuardPathNode(TempPoint).Closed )
02029	            {
02030	                TempList.Length = TempList.Length+1;
02031	                TempList[ TempList.Length-1 ] = TempPoint;
02032	            }
02033	        }
02034	
02035	        TacticalPoint = TempList[Rand( TempList.Length)];
02036	    }
02037	
02038	    //--------------------------------------------------------------
02039	
02040	    function bool StopOrder()
02041	    {
02042	        if( GetFlagState( MyFlag ) != cHome )
02043	            return true;
02044	        else
02045	            return false;
02046	    }
02047	
02048	    //--------------------------------------------------------------
02049	
02050	    function bool AllReady()
02051	    {
02052	        local int Loop , NbReady , NbBot;
02053	
02054	        for( Loop=0;Loop<MyTeam.Length;Loop++ )
02055	        {
02056	            if( ( MyTeam[ Loop ].TeamRole != cDefense ) && ( MyTeam[ Loop ].FindOrder(Order_WaitBeforeAttack ) ) )
02057	            {
02058	                NbBot++;
02059	
02060	                if( CTFBotController(MyTeam[ Loop ]).ReadyToAttack )
02061	                    NbReady++;
02062	            }
02063	
02064	        }
02065	
02066	        if( NbReady == NbBot )
02067	            return true;
02068	        else
02069	            return false;
02070	    }
02071	
02072	    //--------------------------------------------------------------
02073	
02074	Begin :
02075	
02076	    GetRandomWaitPoint();
02077	
02078	    Pawn.ShouldCrouch( false );
02079	
02080	    while( true )
02081	    {
02082	        NavPathStorage( TacticalPoint );
02083	
02084	        if( MoveTarget == none )
02085	        {
02086	            Sleep( 0.5 );
02087	            break;
02088	        }
02089	
02090	        GuardPathNode(TacticalPoint).Closed = true;
02091	
02092	        for( PathIndex = 0; PathIndex < PathCacheSize ; PathIndex ++ )
02093	        {
02094	            if( StopOrder() )
02095	            {
02096	                AddOrder( 75 , Order_SeekTheFlag , "Retrive My Flag",0);
02097	                RemoveOrder(Order_ProtectTheFlag);
02098	            }
02099	
02100	            MoveTarget = PathCache[ PathIndex ];
02101	            Focus=MoveTarget;
02102	
02103	            MoveToward( MoveTarget, Focus , MoveSpeed );
02104	        }
02105	
02106	        if( FullPath )
02107	            break;
02108	    }
02109	
02110	    ReadyToAttack=true;
02111	    Focus = none;
02112	    FocalPoint = vector(TacticalPoint.rotation)*10000+Pawn.Location;
02113	    Pawn.SpineYawControl(true,3000, 1.2);
02114	
02115	    if( Rand( 100 ) < 50 )
02116	        Pawn.ShouldCrouch( true );
02117	    else
02118	        Pawn.ShouldCrouch( false );
02119	
02120	    while( true )
02121	    {
02122	        if( GetFlagState( MyFlag ) == cHome )
02123	            Sleep( 1.0 );
02124	        else
02125	        {
02126	            AddOrder( 75 , Order_SeekTheFlag , "Retrive My Flag",0);
02127	            RemoveOrder(Order_WaitBeforeAttack);
02128	        }
02129	
02130	        if( Level.TimeSeconds - ProtectTime > MaxProtectTime )
02131	            RemoveOrder(Order_WaitBeforeAttack);
02132	
02133	        if( AllReady() )
02134	        {
02135	            Sleep( 1.0 + FRand() );
02136	            RemoveOrder(Order_WaitBeforeAttack);
02137	        }
02138	    }
02139	}
02140	
02141	//__________________________________________________________________
02142	//__________________________________________________________________
02143	//                            ProtectTheHolder
02144	//__________________________________________________________________
02145	//__________________________________________________________________
02146	
02147	state ProtectTheHolder
02148	{
02149	    event BeginState()
02150	    {
02151	        if( DBugBot )
02152	        {
02153	            Log("");
02154	            Log("[ BOT"@ID@"] : *STATE* ---> ProtectTheHolder");
02155	
02156	        }
02157	
02158	        Enemy = none;
02159	        Pawn.ControllerPitch = 0;
02160	
02161	        Pawn.ShouldCrouch( false );
02162	        StopProtect = false;
02163	
02164	        if( Leader == Pawn )
02165	        {
02166	            AddOrder( 75 , Order_BringBackTheFlag , "BringBackTheFlag",0);
02167	            RemoveOrder( Order_ProtectTheHolder );
02168	        }
02169	    }
02170	
02171	    //--------------------------------------------------------------
02172	
02173	    event EndState()
02174	    {
02175	        SetTimer3(0.0,false);
02176	
02177	        if( StopProtect && pawn!=none)
02178	        {
02179	            Pawn.ShouldCrouch( false );
02180	            Pawn.SpineYawControl(false,3000, 1.2);
02181	        }
02182	    }
02183	
02184	    //--------------------------------------------------------------
02185	
02186	    event SeePlayer( Pawn Seen )
02187	    {
02188	        if( ( ! IsEnemy( Seen ) ) || ( VSize( Pawn.Location - Seen.Location ) > 600 ) )
02189	            return;
02190	
02191	        Enemy = Seen;
02192	
02193	        ForceOtherTeamBotToHelpProtector();
02194	
02195	        if( ! FindOrder( Order_Kill ) )
02196	            AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
02197	    }
02198	
02199	    //--------------------------------------------------------------
02200	
02201	    function forceOtherTeamBotToHelpProtector()
02202	    {
02203	        local int Loop;
02204	
02205	        for( Loop=0;Loop<MyTeam.Length;Loop++ )
02206	        {
02207	            if( MyTeam[ Loop ].IsInState('ProtectTheHolder') )
02208	            {
02209	                if( ! MyTeam[ Loop ].FindOrder( Order_Kill ) )
02210	                {
02211	                    MyTeam[ Loop ].Enemy = Enemy;
02212	                    MyTeam[ Loop ].AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
02213	                }
02214	            }
02215	        }
02216	    }
02217	
02218	    //--------------------------------------------------------------
02219	
02220	    function SomeoneWantKillMe( Pawn Agressor )
02221	    {
02222	        if( ( ! IsEnemy( Agressor ) ) || ( VSize( Pawn.Location - Agressor.Location ) > 1000 ) )
02223	            return;
02224	
02225	        Enemy = Agressor;
02226	
02227	        if( ! FindOrder( Order_Kill ) )
02228	            AddOrder(KillOrderPriority,Order_Kill,"Kill",0);
02229	    }
02230	
02231	    //--------------------------------------------------------------
02232	
02233	    function FindPathToMyLeader()
02234	    {
02235	        local actor Path;
02236	
02237	         if( Leader == none || Leader.bIsDead)
02238	            return;
02239	
02240	        Path = ExtendFindPathToward(Leader);
02241	
02242	//        if( Path == none )
02243	//            Path = FindPathToward(Leader);
02244	
02245	        if( Path == none )
02246	            Leader = none;
02247	        else
02248	            MoveTarget = Path;
02249	    }
02250	
02251	    //--------------------------------------------------------------
02252	
02253	    function bool StopOrder()
02254	    {
02255	        if( GetFlagState( EnemyFlag ) == cHome )
02256	        {
02257	            JustRespawn =true;
02258	            return true;
02259	        }
02260	        else
02261	            return false;
02262	    }
02263	
02264	    //--------------------------------------------------------------
02265	
02266	    event Timer3()
02267	    {
02268	        local float DistToLeader;
02269	
02270	        DistToLeader = VSize( Pawn.Location - Leader.Location );
02271	
02272	        if( ! StopProtect )
02273	        {
02274	            if( DistToLeader < 400 + Rand( 200 ) )
02275	            {
02276	                StopProtect = true;
02277	                gotostate('ProtectTheHolder','StraffeBeforeHoldPosition');
02278	            }
02279	        }
02280	        else
02281	        {
02282	            if( DistToLeader > 800 )
02283	            {
02284	                StopProtect = false;
02285	
02286	                Pawn.ShouldCrouch( false );
02287	                Pawn.SpineYawControl(false,3000, 1.2);
02288	
02289	                gotostate('ProtectTheHolder','Begin');
02290	            }
02291	        }
02292	    }
02293	
02294	    //--------------------------------------------------------------
02295	
02296	    event bool NotifyBump(Actor Other);
02297	
02298	    //--------------------------------------------------------------
02299	
02300	Begin:
02301	
02302	    //log(" > Go to Holder");
02303	
02304	    SetTimer3(0.4,true);
02305	    Timer3();
02306	
02307	    Sleep( FRand()/2 );
02308	
02309	    while( true )
02310	    {
02311	        if( StopOrder() )
02312	        {
02313	            //log("   > RemoveOrder for StopOrder");
02314	            RemoveOrder( Order_ProtectTheHolder );
02315	        }
02316	
02317	        FindPathToMyLeader();
02318	
02319	        if( ( Leader == none ) || ( Leader.bIsDead ) )
02320	        {
02321	            //log("   > RemoveOrder for Path");
02322	            RemoveOrder( Order_ProtectTheHolder );
02323	        }
02324	        else
02325	        {
02326	            Pawn.ShouldCrouch( false );
02327	            Focus=MoveTarget;
02328	
02329	            //log("   > MoveToward to"@MoveTarget);
02330	
02331	            MoveToward( MoveTarget, Focus , MoveSpeed );
02332	        }
02333	    }
02334	
02335	StraffeBeforeHoldPosition:
02336	
02337	    Pawn.velocity=vect(0,0,0);
02338	    Pawn.acceleration=vect(0,0,0);
02339	
02340	    if( Rand( 100 ) < 50 )
02341	        UnBlockPos1 = Pawn.Location + ( vector(pawn.rotation) cross (vect(0,0,1)) )*300;
02342	    else
02343	        UnBlockPos1 = Pawn.Location + ( vector(pawn.rotation) cross (vect(0,0,1)) )*(-300);
02344	
02345	    MoveTo( UnBlockPos1, Leader );
02346	
02347	    Pawn.velocity=vect(0,0,0);
02348	    Pawn.acceleration=vect(0,0,0);
02349	
02350	HoldPosition :
02351	
02352	    //log(" > HoldPosition");
02353	
02354	    FindAllNearestWatchPoint(Leader);
02355	
02356	    if( UseableWatchPointList.Length != 0 )
02357	    {
02358	        Focus = none;
02359	        FocalPoint = UseableWatchPointList[ Rand( UseableWatchPointList.Length ) ].Location;
02360	    }
02361	    else
02362	        Focus = Leader;
02363	
02364	    Pawn.SpineYawControl(true,3000, 1.2);
02365	
02366	    if( Rand( 100 ) < 50 )
02367	        Pawn.ShouldCrouch( true );
02368	    else
02369	        Pawn.ShouldCrouch( false );
02370	
02371	    SetTimer3(1.0,true);
02372	
02373	    while( true )
02374	    {
02375	        if( StopOrder() )
02376	            RemoveOrder( Order_ProtectTheHolder );
02377	
02378	        if( ( Leader.bIsDead ) || ( Leader == none ) )
02379	            RemoveOrder( Order_ProtectTheHolder );
02380	
02381	        sleep( 0.5 );
02382	    }
02383	}
02384	
02385	//__________________________________________________________________
02386	//__________________________________________________________________
02387	//                            Dead
02388	//__________________________________________________________________
02389	//__________________________________________________________________
02390	
02391	state Dead
02392	{
02393	    event BeginState()
02394	    {
02395	        super.BeginState();
02396	        JustRespawn=true;
02397	        DontChangeTactikalPoint = false;
02398	    }
02399	}
02400	
02401	//__________________________________________________________________
02402	//__________________________________________________________________
02403	//                            GameEnded
02404	//__________________________________________________________________
02405	//__________________________________________________________________
02406	
02407	state GameEnded
02408	{
02409	    function UpDateOrder(int OldOrder,int NewOrder);
02410	}
02411	
02412	//__________________________________________________________________
02413	
02414	
02415	
02416	
02417	defaultproperties
02418	{
02419	     JustRespawn=True
02420	}

End Source Code